シナリオリクエストが 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 のインストールと設定方法のグラフィックチュートリアル
0x0 パラメータ検証Nest.jsでは、パラメータ検証業務のほとんどをパイプライン方式で実装してい...
Dockerfileの作成yumソースを設定する cd /tmp/docker vim Docker...
この記事では、MySQL 学習ノートの select ステートメントの完全な使用方法を例を使用して説...
まずは違いについて話しましょう最後に、書き換えられたルールは、次の場所と一致させるために書き換えられ...
CSSスタイルファイルで指定 #class td /*表のテキストを左右上下に揃えるように設定する*...
目次1. 準備2. 減圧3. 統合を開始する1. 準備Ckeditor_4.5.7_full + C...
この記事の例では、ポップアップ効果を実現するためのjsの具体的なコードを参考までに共有しています。具...
序文この記事では、div の幅を 100% に設定し、親要素を超えてパディングまたはマージンを設定す...
CSS でテキストアイコンを実装する方法 /*アイコンスタイル*/ .nav-icon-norma...
最近、データベース関連の操作が多くなり、会社の既存の仕様はあまり包括的ではありません。インターネット...
この記事では、年、月、日の3段階のリンクを実現するためのJavaScriptの具体的なコードを参考ま...
1. ウェブサイトのホームページのハイパーテキスト ドキュメントの構成構造は、ユーザーの注意をできる...
目次1. 概念の素早い理解: 1. コンポーネント間でデータを共有する方法: 2. vuex とは何...
現象Apache Spark 2.x を使用すると、Spark ジョブがすべて完了しているにもかかわ...
実際の開発では、MySQL の主キーは重複できず、主キーが自動的にインクリメントされることがあります...