回答(13)
2 years ago
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和其他人)这种方法保证在调用“完成”回调之前处理所有项目 . 您需要使用在回调中更新的计数器 . 取决于索引参数的值不提供相同的保证,因为不保证异步操作的返回顺序 .
使用ES6承诺
(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'));
使用异步库
还有其他异步库,async是最受欢迎的,提供表达您想要的机制 .
编辑
问题的主体已被编辑,以删除以前的同步示例代码,所以我已更新我的答案澄清 . 原始示例使用同步代码来模拟异步行为,因此应用了以下内容:
array.forEach 是synchronous,因此是 res.write ,因此您可以在调用foreach后简单地进行回调:
posts.foreach(function(v, i) {
res.write(v + ". index " + i);
});
res.end();