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などに感謝)このアプローチは、「完了」コールバックを呼び出す前にすべてのアイテムが処理されることを保証します。コールバックで更新されるカウンターを使用する必要があります。非同期操作の戻り順序は保証されないため、indexパラメーターの値によっては同じ保証が得られません。
ES6 Promiseの使用
(promiseライブラリは古いブラウザで使用できます):
同期実行を保証するすべてのリクエストを処理します(例: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();
forEach
メソッドにdone
コールバックパラメータとallDone
コールバックがあると便利です。