1. はじめにこの記事では、 2. es5メソッドes6 が登場する前から、 3. 非同期関数のシリアル実行var アイテム = [ 1, 2, 3, 4, 5, 6 ]; var 結果 = []; 関数 async(arg, コールバック) { console.log('パラメータは ' + arg +' です。1 秒後に結果を返します'); setTimeout(function() { callback(arg * 2); }, 1000); } 関数final(値) { console.log('完了しました: ', 値); } 関数シリーズ(アイテム) { if(アイテム) { 非同期(項目、関数(結果) { 結果をプッシュします。 return series(items.shift()); // すべてのデータを再帰的に実行します }); } それ以外 { final(results[results.length - 1]) を返します。 } } シリーズ(items.shift()); 4. 非同期関数の並列実行上記の関数は一つずつ実行され、前の関数が終了してから次の関数が実行されますが、これは 次のように書くことができます。 var アイテム = [ 1, 2, 3, 4, 5, 6 ]; var 結果 = []; 関数 async(arg, コールバック) { console.log('パラメータは ' + arg +' です。1 秒後に結果を返します'); setTimeout(function() { callback(arg * 2); }, 1000); } 関数final(値) { console.log('完了しました: ', 値); } items.forEach(function(item){// ループ完了 async(item, function(result){ 結果をプッシュします。 if(results.length === items.length){// 完了した関数の数が実行される関数の数と等しいかどうかを判断します final(results[results.length - 1]); } }) }); 5. 非同期関数のシリアル実行と並列実行の組み合わせ多数の非同期データ(数百個)が並列に実行され、各非同期データに大量の(https)リクエストデータが含まれている場合、TCP 接続が不足したり、無数のコールスタックが蓄積されてメモリオーバーフローが発生する可能性があります。そのため、大量のデータを並列に実行するのは容易ではなく、並列方式と直列方式を組み合わせた方法が登場しました。 コードは次のように記述できます。 var アイテム = [ 1, 2, 3, 4, 5, 6 ]; var 結果 = []; var 実行中 = 0; var 制限 = 2; 関数 async(arg, コールバック) { console.log('パラメータは ' + arg +' です。1 秒後に結果を返します'); setTimeout(function() { callback(arg * 2); }, 1000); } 関数final(値) { console.log('完了しました: ', 値); } 関数ランチャー() { while(実行中 < limit && items.length > 0) { var item = items.shift(); 非同期(項目、関数(結果) { 結果をプッシュします。 実行中--; (アイテムの長さ>0)の場合{ ランチャー(); } そうでない場合(実行中 == 0) { 最終(結果); } }); 実行中++; } } ランチャー(); 6. es6メソッド
tiny-async-pool、es6-promise-pool、p-limit
function PromiseLimit(funcArray, limit = 5) { // 5つのデータを同時に実行 let i = 0; 定数結果 = []; const 実行 = []; 定数キュー = 関数() { if (i === funcArray.length) の場合、Promise.all(executing) を返します。 const p = funcArray[i++](); 結果をpushします。 const e = p.then(() => execute.splice(executing.indexOf(e), 1)); 実行中.push(e); if (実行中の長さ >= 制限) { Promise.race(実行中).then( を返す () => キュー()、 e => Promise.reject(e) ); } Promise.resolve() を返します。その後 (() => queue()); }; キュー()を返します。その後()=> Promise.all(結果)); } 使用: // テストコード const result = []; (インデックス = 0、インデックス < 10、インデックス++) { 結果.push(関数() { 新しい Promise を返します ((resolve, reject) => { console.log("start" + インデックス、新しい Date().toLocaleString()); タイムアウトを設定する(() => { 解決(インデックス); console.log("End" + インデックス、新しいDate().toLocaleString()); }, parseInt(Math.random() * 10000)); }); }); } PromiseLimit(結果).then(データ => { コンソールにログ出力します。 }); テストコードを修正し、ランダムな失敗ロジックを追加する // テストコードを変更して、ランダムに失敗または成功するようにします。const result = []; (インデックス = 0、インデックス < 10、インデックス++) { 結果.push(関数() { 新しい Promise を返します ((resolve, reject) => { console.log("start" + インデックス、新しい Date().toLocaleString()); タイムアウトを設定する(() => { もし(Math.random() > 0.5){ 解決(インデックス); } それ以外 { 拒否(インデックス); } console.log("End" + インデックス、新しいDate().toLocaleString()); }, parseInt(Math.random() * 1000)); }); }); } PromiseLimit(結果).then( データ => { console.log("成功", データ); }, データ => { console.log("失敗", データ); } ); 7. asyncとawaitをpromiseと組み合わせる非同期関数 PromiseAll(promises,batchSize=10) { 定数結果 = []; while(promises.length > 0) { const データ = Promise.all(promises.splice(0,batchSize)) を待機します。 結果.push(...データ); } 結果を返します。 } この文章には 2 つの問題があります。
改善点は次のとおりです。 非同期関数 asyncPool(配列、poolLimit、iteratorFn) { 定数ret = []; const 実行 = []; for (配列のconst項目) { const p = Promise.resolve().then(() => iteratorFn(item, array)); ret.push(p); プール制限 <= 配列の長さの場合 { const e = p.then(() => execute.splice(executing.indexOf(e), 1)); 実行中.push(e); 実行中の長さ >= poolLimit の場合 { Promise.race(実行中) を待機します。 } } } Promise.all(ret) を返します。 } 使用: const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i)); asyncPool( [1000, 5000, 3000, 2000], 2,timeout)を返します。その後(結果 => { ... }); JavaScript の非同期操作におけるシリアル操作と並列操作に関するこの記事はこれで終わりです。JavaScript の非同期操作におけるシリアル操作と並列操作に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
>>: seata docker 高可用性デプロイメントの詳細な紹介
目次補間式方法計算された要約する今日は、Vue の計算プロパティについてお話ししましょう。計算プロパ...
目次概要問題の説明循環リンクリスト順序付き配列数学的再帰要約する概要ジョセフ・リング問題は、ジョセフ...
目次問題のシナリオ:解決: 1. フィールドを個別にチェックする2. フォームフィールドの下のフィー...
docker リモート API を学習した学生であれば、ポート 2375 についてよくご存知だと思い...
入力ボックスには、コンテンツを入力するときに常に入力履歴が表示されます。これを無効にする現在の方法は...
1. Vue レスポンシブの使用法を確認する Vue の応答性は、私たち全員がよく知っています。 ...
テーブル構造を編集するための MySQL の alter コマンドの使用。具体的な内容は以下のとおり...
この記事では、Nodejs 開発プロセスで遭遇する配列の特性によって発生する問題と解決策、および配列...
リンク A のセマンティクス、ライティング スタイル、およびベスト プラクティス。私は JavaEy...
目次0. モジュールとは何か1.モジュールの読み込み1.1 方法1 1.2 方法2 2. 輸出と輸入...
1. Centos7.6システムを作成し、システムを最適化する1. NetworkManagerをオ...
目次1. データをバックアップするためのmysqldumpコマンド2. 一般的なmysqldump操...
目次序文1. システムサービス制御1. システムctl 2. ターゲット3. 共通システムサービス4...
最終的な効果は次のようになります。アニメーションは2つのステップに分かれていますランニング軌道を開発...
1. 基本ライン 2. 特殊効果(効果は独立しておらず、互いに組み合わせることができます) 1. 両...