[解決済み】非同期のforEachコールバックがすべて完了した後にコールバックする。
2022-04-18 08:32:42
質問
タイトルの通りです。どうすればいいのでしょうか?
を呼び出したい。
whenAllDone()
forEachループが各要素を通過し、非同期処理を行った後。
[1, 2, 3].forEach(
function(item, index, array, done) {
asyncFunction(item, function itemDone() {
console.log(item + " done");
done();
});
}, function allDone() {
console.log("All done");
whenAllDone();
}
);
このように動作させることは可能でしょうか?forEachの第2引数がコールバック関数で、それがすべての反復を通過した後に実行される場合?
期待される出力
3 done
1 done
2 done
All done!
解決方法は?
Array.forEach
はこのような機能を提供しませんが、あなたが望むことを実現するための方法がいくつかあります。
単純なカウンターを使用する
function callback () { console.log('all done'); }
var itemsProcessed = 0;
[1, 2, 3].forEach((item, index, array) => {
asyncFunction(item, () => {
itemsProcessed++;
if(itemsProcessed === array.length) {
callback();
}
});
});
(@vanuan と他の人に感謝) このアプローチは、"done" コールバックを呼び出す前にすべてのアイテムが処理されることを保証します。コールバックで更新されるカウンターを使用する必要があります。index パラメータの値に依存すると、非同期処理の戻り順が保証されないため、同じ保証は得られません。
ES6プロミスの使用
(古いブラウザではプロミス・ライブラリが使用できます)。
-
同期実行を保証する全リクエストの処理(例:1→2→3)
function asyncFunction (item, cb) { setTimeout(() => { console.log('done with', item); cb(); }, 100); } let requests = [1, 2, 3].reduce((promiseChain, item) => { return promiseChain.then(() => new Promise((resolve) => { asyncFunction(item, resolve); })); }, Promise.resolve()); requests.then(() => console.log('done'))
-
非同期リクエストをすべて同期実行せずに処理する(2が1より早く終了する可能性あり)
let requests = [1,2,3].map((item) => { return new Promise((resolve) => { asyncFunction(item, resolve); }); }) Promise.all(requests).then(() => console.log('done'));
非同期ライブラリの使用
他にも非同期ライブラリがあります。 非同期 は、あなたが望むものを表現するためのメカニズムを提供する最も一般的なものです。
編集質問本文が編集され、以前の同期のサンプルコードが削除されたので、明確にするために私の答えを更新しました。 元の例では、非同期の動作をモデル化するために同期のようなコードを使用していたので、次のように適用しました。
array.forEach
は
シンクロナス
であり、同様に
res.write
そのため、コールバックをforeachの呼び出しの後に置くだけでよいのです。
posts.foreach(function(v, i) {
res.write(v + ". index " + i);
});
res.end();
関連
-
[解決済み】パッシブイベントリスナー内部でpreventDefaultができない
-
[解決済み】 Uncaught TypeError: data.push is not a function
-
[解決済み】Uncaught ReferenceError。Reactが定義されていない
-
[解決済み】SyntaxError: ChromeのJavascriptコンソールでUnexpected Identifierが発生する。
-
[解決済み】Babel NodeJS ES6: SyntaxError: 予期しないトークンのエクスポート
-
[解決済み】HTMLの最初の行に予期しないトークン<がある。
-
[解決済み】 \u003C とは何ですか?
-
[解決済み] エラーが発生しました。クライアントに送信された後にヘッダーを設定できない
-
[解決済み] 関数内で変数を変更した後、変数が変更されないのはなぜですか?- 非同期コードリファレンス
-
[解決済み] 非同期ネットワークリクエストのswift forループの実行が終了するまで待つ
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 Uncaught TypeError: data.push is not a function
-
[解決済み】TypeError: $(...).DataTable は関数ではありません。
-
[解決済み】Uncaught ReferenceError: angular is not defined - AngularJSが動作しない。
-
[解決済み】Angular JS Uncaught Error。[インジェクター:モジュラー]。
-
[解決済み】WebpackとBabelで「このファイルタイプを扱うには適切なローダーが必要な場合があります。
-
[解決済み】ETIMEDOUTエラーの対処方法は?
-
[解決済み】Uncaught TypeError: 未定義のプロパティ 'msie' を読み取れない - jQuery tools
-
[解決済み】HTMLの最初の行に予期しないトークン<がある。
-
[解決済み】未定義のプロパティ 'forEach' を読み取ることができない
-
[解決済み] JavaScript, Node.js: Array.forEachは非同期なのか?