Node.js の非同期イテレータの詳細な説明

Node.js の非同期イテレータの詳細な説明

序文

非同期イテレータは Node.js v10.0.0 から存在しており、最近コミュニティで注目を集めています。この記事では、非同期イテレータの役割について説明し、非同期イテレータが何に使用される可能性があるかという疑問にも取り組みます。

非同期イテレータとは何ですか?

では、非同期イテレータとは何でしょうか?これらは実質的に、以前使用可能だったイテレータの非同期バージョンです。反復の値と最終ステータスがわからない場合は、非同期イテレータを使用できます。最終的には、{value:any、done:boolean} オブジェクトに解決できる promise が得られます。また、非同期イテレータをループするのに役立つ for-await-of ループも用意しました。同期イテレータの for-of ループと同じです。

非同期イテレータの定数は[1, 2, 3]です。
asyncIterable[Symbol.asyncIterator] = 非同期関数*() {
  (i = 0 とします; i < asyncIterable.length; i++) {
    yield { 値: asyncIterable[i], 完了: false }
  }
  結果: true
};

(非同期関数() {
  for await (asyncIterable の const 部分) {
    console.log(一部);
  }
})();

通常の for-of ループとは対照的に、for-await-of ループは、受信した各 Promise が解決されるまで待機してから、次の Promise に進みます。

現在、ストリーム以外に非同期反復をサポートする構造は多くありませんが、ここに示すように、反復可能な構造に表記法を手動で追加できます。

非同期イテレータストリームとして

非同期イテレータはストリームを処理するときに非常に便利です。読み取り可能、書き込み可能、​​二重、および変換ストリームはすべて非同期イテレータをサポートします。

非同期関数 printFileToConsole(path) {
  試す {
    const readStream = fs.createReadStream(path, { エンコーディング: 'utf-8' });

    for await (const chunk of readStream) {
      console.log(チャンク);
    }

    console.log('EOF');
  } キャッチ(エラー) {
    コンソール.log(エラー);
  }
}

このようにコードを記述すると、反復処理して各データ チャンクを取得するときにデータ イベントと終了イベントをリッスンする必要がなくなり、ストリーム自体が終了すると for-await-of ループも終了します。

ページング機能を備えたAPIの呼び出し

非同期反復を使用して、ページネーションを使用するソースからデータを簡単に取得することもできます。これを行うには、Node https リクエスト メソッドが提供するストリームから応答本文を再構築する方法も必要です。 https リクエストとレスポンスは Node 内のストリームなので、ここで非同期イテレータを使用することもできます。

定数 https = require('https');

関数 homebrewFetch(url) {
  新しい Promise(async (resolve, reject) => { を返します。
    const req = https.get(url, 非同期関数(res) {
      (res.statusCode >= 400)の場合{
        拒否を返します(新しいエラー(`HTTP ステータス: ${res.statusCode}`));
      }

      試す {
        本文を '' とします。

        /*
          ストリーム内のデータをリッスンする代わりに、
          for-await-ofを使用してデータチャンクを追加することができます
          レスポンス本文の残りの部分*/
        for await (const chunk of res) {
          本体 += チャンク;
        }
    
        // 本文がない場合の処理​​ if (!body) resolve({});
        // 本文は文字列なので、JSON を取得するには解析する必要があります。const result = JSON.parse(body);
        解決(結果);
      } キャッチ(エラー) {
        拒否(エラー)
      }
    });

    要求を待機します。
    要求を終了します();
  });
}

Cat API にリクエストを送信して、10 匹ずつの猫の写真を取得します。また、cat API の過負荷を回避するために、リクエスト間に 7 秒の遅延を追加し、最大ページ数を 5 にします。

また、cat API の過負荷を回避するために、リクエスト間に 7 秒の遅延を追加し、最大ページ数を 5 にします (過負荷になると壊滅的な結果となるため)。

関数 fetchCatPics({ limit, page, done }) {
  homebrewFetch を返します(`https://api.thecatapi.com/v1/images/search?limit=${limit}&page=${page}&order=DESC`)
    .then(本文 => ({ 値: 本文、完了 }));
}

関数catPics({limit}){
  戻る {
    [Symbol.asyncIterator]: 非同期関数*() {
      現在のページを 0 にします。
      // 5ページ後に停止
      現在のページが 5 未満の場合
        試す {
          const cats = fetchCatPics({ currentPage, limit, done: false }) を待機します。
          console.log(`${limit} 匹の猫を取得しました`);
          猫を飼う;
          現在のページ++;
        } キャッチ(エラー) {
          console.log('すべての猫を取得中にエラーが発生しました!');
          コンソール.log(エラー);
        }
      }
    }
  };
}

(非同期関数() {
  試す {
    for await (let catPicPage of catPics({ limit: 10 })) {
      コンソールにログ出力します。
      // リクエスト間で7秒間待機する
      新しい Promise(resolve => setTimeout(resolve, 7000)) を待機します。
    }
  } キャッチ(エラー) {
    コンソール.log(エラー);
  }
})()

こうすることで、7 秒ごとに猫の写真のページ全体が自動的に取得され、お楽しみいただけます。

ページ間を移動するより一般的な方法は、 next メソッドと previous メソッドを実装し、それらをコントロールとして公開することです。

関数actualCatPics({limit}){
  戻る {
    [シンボル.asyncIterator]: () => {
      ページを 0 にします。
      戻る {
        次へ: 関数() {
          ページ++;
          fetchCatPics({page,limit,done:false}) を返します。
        },
        前: 関数() {
          (ページ > 0) {
            ページ - ;
            fetchCatPics({page,limit,done:false}) を返します。
          }
          fetchCatPics({ page: 0, limit, done: true }); を返します。
        }
      }
    }
  };
}

試す {
    const someCatPics = 実際のCatPics({ 制限: 5 });
    const { next, previous } = someCatPics[Symbol.asyncIterator]();
    次に()します。その後(console.log);
    次に()します。その後(console.log);
    前回の().その後(console.log);
} キャッチ(エラー) {
  コンソール.log(エラー);
}

ご覧のとおり、非同期イテレータは、データのページを取得したり、アプリケーションの UI で無限スクロールなどの操作を実行したりするときに非常に便利です。

これらの機能はしばらく前からブラウザに搭載されており、Chrome v63 以降、Firefox v57 以降、Safari v11.1 で利用できます。ただし、現在 IE と Edge では利用できません。

上記は、Node.js の非同期イテレータの詳細な説明です。Node.js の非同期イテレータの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • NodeJs の高メモリ使用量のトラブルシューティング実戦記録
  • Nodejs 組み込み暗号化モジュールを使用してピアツーピアの暗号化と復号化を実現する詳細な説明
  • Node.js組み込みモジュールの詳細な説明
  • Nodejs モジュール システムのソースコード分析
  • JS と Nodejs におけるイベント駆動型開発についての簡単な説明
  • Nodejs でモジュール fs ファイルシステムを使用する方法
  • Node.js コード実行をバイパスするためのヒントのまとめ
  • Nodejs 探索: シングルスレッドの高並行性の原理を深く理解する
  • Nodejs エラー処理プロセス記録
  • Node.js を使用して C# のデータ テーブル エンティティ クラス生成ツールを作成する方法

<<:  Tomcat の構成と最適化ソリューションの詳細な説明

>>:  CentOS 7.4 にソースコードから MySQL 8.0 をインストールするための詳細なチュートリアル

推薦する

Tomcatはスレッドプールを使用してリモート同時リクエストを処理します。

Tomcatが同時リクエストを処理する方法を理解することで、スレッドプール、ロック、キュー、および...

JS で async と await を使用する方法

目次1. 非同期2. 待つ: 3. 包括的なアプリケーション1. 非同期async 、非同期コードが...

C# は MySQL コマンドラインのバックアップとリカバリを実装します

MySQL データベースをバックアップするためのツールは多数あります。過去 2 日間で、C# を使用...

div が contentEditable=true に設定されている場合、コンテンツをリセットした後にカーソルを配置することはできません。

最近、絵文字にコメントする機能が必要なコメント機能に取り組んでいたため、 contentEditab...

XHTML 入門チュートリアル: テーブルタグの応用

<br />テーブルは XHTML では扱いにくいタグなので、このセクションで理解するだ...

MySQLデータベースを作成し、中国語の文字をサポートする方法

まずMySQLの公式ドキュメントを見てみましょう: 5.7 {データベース | スキーマ} を作成 ...

Dockerコンテナアプリケーションログの表示方法

docker アタッチコマンドdocker attach [options] 容器実行中のコンテナに...

Docker 用ビジュアル UI 管理ツール Portainer のインストールと使用方法の分析

Portainer は、ステータス表示パネル、アプリケーション テンプレートの迅速な展開、コンテナ ...

ReactプロジェクトでのTypeScriptの実装

目次1. はじめに2. 使用方法ステートレスコンポーネントステートフルコンポーネント制御コンポーネン...

WeChatミニプログラムの基本チュートリアル:Echartの使用

序文まずは最終的な効果を見てみましょう。私が自分で作った小さなデモです。まずEChartsの公式サイ...

Zabbix WEB 監視実装プロセス図

Zabbix独自のWEBインターフェースを例に、Web監視の設定を行います。環境: zabbix4....

1 つの記事で React における Redux の初期の使用を理解する

Redux はデータ状態管理プラグインです。React や Vue を使用してコンポーネント化された...

Vue は小数点付きの星評価を実装します

この記事では、小数点付きの星評価を実装するためのVueの具体的なコードを参考までに共有します。具体的...

複数の古いプレーヤーの埋め込みコード

ウェブページに表示されるプレーヤーは、WMP/RealPlayer/Flash Player に過ぎ...

MySQL がユーザー名とパスワードの漏洩を引き起こす可能性のある Riddle の脆弱性を公開

MySQL バージョン 5.5 および 5.6 を標的とする Riddle 脆弱性により、中間者攻撃...