非同期トラバーサル非同期トラバーサルを説明する前に、ES6 の同期トラバーサルを思い出してみましょう。 ES6 の定義によると、反復は主に 3 つの部分で構成されます。 反復可能 まず、Iterable の定義を見てみましょう。 インターフェース Iterable { [Symbol.iterator]() : イテレータ; } Iterable は、このオブジェクトにトラバース可能なデータが含まれており、Iterator を生成できるファクトリ メソッドを実装する必要があることを意味します。 イテレータ インターフェースイテレータ{ 次の(): イテレータの結果; } イテレータは Iterable から構築できます。 Iterator はカーソルに似た概念であり、IteratorResult には next を通じてアクセスできます。 イテレータ結果 IteratorResult は、次のメソッドが呼び出されるたびに取得されるデータです。 インターフェースIteratorResult { 値: 任意; 完了: ブール値; } 取得するデータを表す値に加えて、IteratorResult には、トラバーサルが完了したかどうかを示す done もあります。 以下は配列を反復処理する例です。
ただし、上記の例では同期データを走査しています。http 側からダウンロードしたファイルなどの非同期データを取得する場合は、ファイルを 1 行ずつ走査する必要があります。データ行の読み取りは非同期操作であるため、非同期データの走査が必要になります。 非同期ファイル読み取りメソッド readLinesFromFile を追加すると、同期トラバーサル メソッドは非同期には適用されなくなります。 // (const line of readLinesFromFile(fileName)) には適用されなくなりました { console.log(行); } 非同期的に 1 行を読み取り、それを同期的に走査する操作を Promise にカプセル化できるのだろうかと疑問に思うかもしれません。 アイデアは良いのですが、この場合、非同期操作が完了したかどうかを検出することは不可能です。したがって、この方法は実行可能ではありません。 そこで ES9 では非同期トラバーサルの概念が導入されました。 1. 非同期反復可能オブジェクトの反復子を取得するには、Symbol.asyncIterator を使用できます。 2. 非同期イテレータの next() メソッドは、IteratorResults を含む Promises オブジェクトを返します。 それでは、非同期トラバーサルの API 定義を見てみましょう。 インターフェースAsyncIterable { [Symbol.asyncIterator]() : AsyncIterator; } インターフェースAsyncIterator { 次のメソッド: Promise<IteratorResult>; } インターフェースIteratorResult { 値: 任意; 完了: ブール値; } 非同期トラバーサル アプリケーションを見てみましょう。 定数 asyncIterable = createAsyncIterable(['a', 'b']); asyncIterator は、 .asyncIterable のインスタンスを生成する。 asyncIterator.next() .then(iterResult1 => { console.log(iterResult1); // { 値: 'a'、完了: false } asyncIterator.next() を返します。 }) .then(iterResult2 => { console.log(iterResult2); // { 値: 'b'、完了: false } asyncIterator.next() を返します。 }) .then(iterResult3 => { console.log(iterResult3); // { 値: undefined、完了: true } }); その中で、createAsyncIterable は同期反復可能オブジェクトを非同期反復可能オブジェクトに変換します。次のセクションで、これがどのように生成されるかを見ていきます。 ここでは主に asyncIterator のトラバーサル操作に焦点を当てます。 ES8 では Async 演算子が導入されたため、上記のコードを Async 関数を使用して書き直すこともできます。 非同期関数f(){ 定数 asyncIterable = createAsyncIterable(['a', 'b']); asyncIterator は、 .asyncIterable のインスタンスを生成する。 console.log(asyncIterator.next() を待機します); // { 値: 'a'、完了: false } console.log(asyncIterator.next() を待機します); // { 値: 'b'、完了: false } console.log(asyncIterator.next() を待機します); // { 値: 未定義、完了: true } } 非同期反復可能トラバーサル同期反復可能オブジェクトを走査するには for-of を使用し、非同期反復可能オブジェクトを走査するには for-await-of を使用します。 非同期関数f(){ await (const x of createAsyncIterable(['a', 'b'])) { コンソールログ(x); } } // 出力: // は // ば await は async 関数内に配置する必要があることに注意してください。 非同期トラバーサルで例外が発生した場合は、for-await-of で try catch を使用して例外をキャッチできます。 関数createRejectingIterable() { 戻る { [シンボル.asyncIterator]() { これを返します。 }, 次() { Promise.reject(new Error('Problem!')) を返します。 }, }; } (非同期関数() { 試す { await (const x of createRejectingIterable()) { コンソールログ(x); } } キャッチ (e) { コンソールエラー(e); // エラー: 問題! } })(); 同期イテラブルは同期イテレータを返し、次のメソッドは {value, done} を返します。 for-await-of を使用すると、同期イテレータは非同期イテレータに変換されます。返された値は Promise に変換されます。 同期 next 自体によって返される値が Promise オブジェクトである場合、非同期の戻り値は同じ Promise のままです。 つまり、次の例に示すように、Iterable<Promise<T>> を AsyncIterable<T> に変換します。 非同期関数main() { const syncIterable = [ Promise.resolve('a')、 Promise.resolve('b')、 ]; await (const x of syncIterable) { コンソールログ(x); } } 主要(); // 出力: // は // ば 上記の例では、同期 Promise を非同期 Promise に変換します。 非同期関数main() { 待機(const x of ['a', 'b']) { コンソールログ(x); } } 主要(); // 出力: // は // d 上記の例では、同期定数を Promise に変換します。 結果は同じであることがわかります。 非同期反復生成上記の例に戻ると、createAsyncIterable(syncIterable) を使用して syncIterable を AsyncIterable に変換します。 このメソッドがどのように実装されるか見てみましょう: 非同期関数* createAsyncIterable(syncIterable) { for (const syncIterable の要素) { 要素を生成します。 } } 上記のコードでは、通常のジェネレーター関数の前に async を追加しています。これは、非同期ジェネレーターであることを意味します。 通常のジェネレーターの場合、 next メソッドが呼び出されるたびに、オブジェクト {value, done} が返されます。このオブジェクトは、yield 値をカプセル化したものです。 非同期ジェネレーターの場合、 next メソッドが呼び出されるたびに、オブジェクト {value, done} を含む promise オブジェクトが返されます。このオブジェクトは、yield 値をカプセル化したものです。 Promise オブジェクトが返されるため、次のメソッドを再度呼び出す前に、非同期実行の結果が完了するのを待つ必要はありません。 Promise.all を使用すると、すべての非同期 Promise 操作を同時に実行できます。 asyncGenObj は、createAsyncIterable を呼び出します。 const [{値:v1},{値:v2}] = await Promise.all([ asyncGenObj.next()、asyncGenObj.next() ]); console.log(v1, v2); // アブ createAsyncIterable では、同期 Iterable から非同期 Iterable を作成します。 次に、非同期 Iterable から非同期 Iterable を作成する方法を見てみましょう。 前のセクションでは、for-await-of を使用して非同期 Iterable からデータを読み取ることができることがわかったので、次のように使用できます。 非同期関数* prefixLines(asyncIterable) { for await (asyncIterableのconst行) { '> ' + 行を生成します。 } } ジェネレータの記事では、ジェネレータ内でジェネレータを呼び出すことについて説明しました。つまり、プロデューサーでは、yield* を使用して別のジェネレーターが呼び出されます。 同様に、非同期ジェネレータでも同じことを行うことができます。 非同期関数* gen1() { 'a' を生成します。 'b' を生成します。 2を返します。 } 非同期関数* gen2() { const 結果 = yield* gen1(); // 結果 === 2 } (非同期関数() { gen2() の const x を待機します。 コンソールログ(x); } })(); // 出力: // は // ば 非同期ジェネレーターで例外がスローされた場合、その例外も Promise にラップされます。 非同期関数* asyncGenerator() { 新しいエラーをスローします('問題があります!'); } asyncGenerator().next() .catch(err => console.log(err)); // エラー: 問題あり! 非同期メソッドと非同期ジェネレーター非同期メソッドは、 async 関数を使用して宣言され、 Promise オブジェクトを返すメソッドです。 関数内で返される例外またはスローされる例外は、返される Promise の値として使用されます。 (非同期関数() { 'hello' を返します。 })() .then(x => console.log(x)); // こんにちは (非同期関数() { 新しいエラーをスローします('問題があります!'); })() .catch(x => console.error(x)); // エラー: 問題あり! 非同期ジェネレーターは、async 関数 * を使用して宣言されたメソッドです。非同期反復可能オブジェクトを返します。 iterable の next メソッドを呼び出すと、Promise が返されます。非同期ジェネレータによって生成された値は、Promise の値を埋めるために使用されます。ジェネレーターで例外がスローされた場合、それは Promise によってもキャッチされます。 非同期関数* gen() { 'hello' を返します。 } 定数 genObj = gen(); genObj.next().then(x => console.log(x)); // { 値: 'hello'、完了: false } 以上がES9の新機能である非同期反復の詳細な説明です。ES9の新機能である非同期反復の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: CentOS 7.x のマスターおよびスレーブ DNS サーバーの展開
目次1. はじめに1.1 原則1.2 プロセス1.3 特徴1.4 githubアドレス2. テスト環...
<br />多くのウェブサイト デザイナーが犯す最も一般的な間違いは、ウェブページが I...
前回の記事では、beforeとafterの擬似要素を使用してMaterial Designスタイルの...
目次背景例誤解 - コールスタックを表示するためにウォッチでブレークポイントを設定する正しいアプロー...
まず、例を挙げてみましょう(読みたくない場合は、以下の要約だけ読んでください)。 order_typ...
目次1. JSの特徴1.1 マルチパラダイム1.2 説明1.3 シングルスレッド1.4 ノンブロッキ...
この記事では、例を使用して、MySQL でストアド プロシージャを作成し、ループでレコードを追加する...
今日は、早速本題に入り、面接中に尋ねられた質問、つまりキープアライブ コンポーネントのキャッシュ原理...
面接の経験によっては、CSS に関する質問がよく見られ、CSS を使用して三角形を描画する方法につい...
Linux はオープン システムです。インターネット上には、既成のプログラムやツールが多数存在します...
1. web01にzabbix-agentをインストールするZabbix ウェアハウスをデプロイする...
注意事項1. まず、mysql インストール ディレクトリに次の内容の my.ini ファイルを作成...
国務院は本日、新型コロナウイルス感染症との闘いで殉教した方々と犠牲者に対し、全国各民族人民の深い哀悼...
Fuser コマンドとは何ですか? fuser コマンドは、特定のファイル、ディレクトリ、またはソケ...
目次CentOS7環境での設定コマンド手順1. DHCP設定ファイルを設定する2. グローバル構成を...