シナリオリクエストが 10 件あるが、同時リクエストの最大数は 5 件で、リクエスト結果が必要であるとします。これは、単純な同時リクエスト制御です。 シミュレーションsetTimeoutを使用してリクエストの簡単なシミュレーションを実行します startTime を Date.now() とします。 const タイムアウト = (タイムアウト: 数値, ret: 数値) => { 戻り値 (idx?: 任意) => 新しいPromise((resolve) => { タイムアウトを設定する(() => { const compare = Date.now() - startTime; console.log(`${Math.floor(compare / 100)}00 で return`, ret); 解決(idx); }、 タイムアウト); }); }; 定数timeout1 = timeout(1000, 1); 定数timeout2 = timeout(300, 2); 定数timeout3 = タイムアウト(400, 3); 定数timeout4 = タイムアウト(500, 4); 定数timeout5 = タイムアウト(200, 5); このようにリクエストをシミュレートすることで、本質はPromiseになります 同時実行制御がない場合定数実行 = 非同期() => { 開始時刻 = Date.now(); Promise.all([ を待つ タイムアウト1()、 タイムアウト2()、 タイムアウト3()、 タイムアウト4()、 タイムアウト5()、 ]); }; 走る(); 200で5を返す 300で2を返す 400で3を返す 500で4を返す 1000で1を返す 出力は 5 2 3 4 1 となっており、タイムアウト時間に応じて出力されていることがわかります。 同時実行条件同時接続の最大数が2であると仮定して、クラスを作成します クラスConcurrent { プライベートmaxConcurrent: 数値 = 2; コンストラクター(count: number = 2) { this.maxConcurrent = カウント; } } 最初の同時実行制御考えてみてください。同時実行の最大数に応じて Promise 配列を分割します。Promise が満たされた場合はそれを削除し、保留中の Promise を追加します。 Promise.raceはこの要件を満たすのに役立ちます クラスConcurrent { プライベートmaxConcurrent: 数値 = 2; コンストラクタ(count: number = 2) { this.maxConcurrent = カウント; } パブリック非同期useRace(fns: Function[]) { const 実行中: any[] = []; // 同時実行数に応じて Promise を追加します // Promise はインデックスをコールバックするので、どの Promise が解決されたかを知ることができます (let i = 0; i < this.maxConcurrent; i++) { (fns.長さ)の場合{ const fn = fns.shift()!; 実行中.push(fn(i)); } } 定数ハンドル = 非同期() => { if (fns.length) { const idx = await Promise.race<number>(running); const nextFn = fns.shift()!; // 完了した Promise を削除し、新しいものを runing.splice(idx, 1, nextFn(idx)); に配置します。 ハンドル(); } それ以外 { // 配列がクリアされている場合は、実行される Promise がないことを意味します。これを Promise.all に変更できます。 Promise.all(実行中) を待機します。 } }; ハンドル(); } } 定数実行 = 非同期() => { const コンカレント = 新しい Concurrent(); 開始時刻 = Date.now(); 同時実行のuseRace([タイムアウト1、タイムアウト2、タイムアウト3、タイムアウト4、タイムアウト5])を待機します。 }; 300で2を返す 700で3を返す 1000で1を返す 1200に5を返す 1200に4に戻る 出力が変化したことがわかります。なぜこのようなことが起こるのでしょうか? 分析してみましょう。同時接続の最大数は 2 です。
2番目のオプションawaitメカニズムを使うことができます。これは実際にはちょっとしたトリックです await 式は、現在の async 関数の実行を一時停止し、Promise が完了するまで待機します。 Promise が満たされると、コールバックの解決関数パラメータが await 式の値として使用され、非同期関数の実行が続行されます。 現在の同時リクエスト数が最大同時リクエスト数を超える場合は、新しい Promise を設定して待機できます。他のリクエストが完了するのを待機している場合は、解決して待機を削除します。そのため、現在の同時リクエスト数と、解決コールバック関数を格納する配列という 2 つの新しい状態を追加する必要があります。 クラスConcurrent { プライベートmaxConcurrent: 数値 = 2; プライベートリスト: Function[] = []; プライベートcurrentCount: 数値 = 0; コンストラクタ(count: number = 2) { this.maxConcurrent = カウント; } パブリック非同期追加(fn:関数) { this.currentCount += 1; // 同時接続の最大数が最大値を超えた場合 if (this.currentCount > this.maxConcurrent) { // wait は Promise であり、resolve が呼び出される限り満たされます。const wait = new Promise((resolve) => { this.list.push(解決) を実行します。 }); //resolve が呼び出されない場合、ここで await wait がブロックされます。 } //関数を実行する await fn(); this.currentCount -= 1; if (this.list.length) { // 解決を取り出して呼び出すと、待機が完了し、以下を実行できるようになります。const resolveHandler = this.list.shift()!; ハンドラを解決します。 } } } 定数実行 = 非同期() => { const コンカレント = 新しい Concurrent(); 開始時刻 = Date.now(); 同時実行を追加します(タイムアウト1); 同時実行を追加します(タイムアウト2)。 同時実行を追加します(timeout3); 同時実行を追加します(タイムアウト4)。 同時実行を追加します(timeout5); }; 走る(); 300で2を返す 700で3を返す 1000で1を返す 1200に5を返す 1200に4に戻る 要約するどちらの方法でも並行制御を実現できますが、実装方法が異なります。主に Promise によって実装されます。また、実装方法は異常事態を考慮しておらず、自分で追加できる可能性があります。 これで、JavaScript/TypeScript で同時リクエスト制御を実装するサンプルコードに関する記事は終了です。JavaScript の同時リクエスト制御に関する詳細については、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: js 加算、減算、乗算、除算の正確な計算方法のサンプルコード
>>: MySQL 5.7.17 winx64 のインストールと設定方法のグラフィックチュートリアル
1. MySQL 5.7 のアンインストール1.1查看yum是否安裝過mysql CD yum li...
この記事では、Webページの画像の回転を実現するためのjsの具体的なコードを参考までに共有します。具...
MySQL レプリケーション テーブルの詳細な説明テーブル構造、インデックス、デフォルト値などを含む...
Docker SwarmについてDocker Swarm は次の 2 つの部分で構成されます。 D...
この記事では、jQueryブリージングカルーセル制作原理の具体的なプロセスを参考までに紹介します。具...
1. オブジェクト指向のクラス継承これまでの章では、JavaScript のオブジェクト モデルがプ...
序文最近、プロジェクトで :first-child を使用したのですが、すぐに思いつきました。これは...
Linux に VMWare をインストールするには、公式 Web サイト https://www....
問題の説明今日、ページ スタイルを変更していたときに、子要素にmargin-top設定したのに、子要...
効果効果は以下のとおりです実装のアイデアbox-shadow プロパティを使用して、複数の灰色の円...
インストール中に遭遇した問題を記録しておきますので、皆様のお役に立てれば幸いです。 1. ダウンロー...
この記事ではクラスタの展開に関連する内容は紹介しませんバージョン制約Docker エンジン >...
各ブラウザの select タグのプロパティと各ブラウザのサポートが多少異なるため、各ブラウザでの選...
目次1. psutilパッケージをインストールする次に、オペレーティングシステム内のすべてのサービス...
区切り文字なしの文字列抽出質問の要件データベース内のフィールド値:実装効果: 1行のデータを複数行に...