正如标题所示。我怎么做呢?
我想在foreach循环遍历每个元素并完成一些异步处理后调用whenAllDone()。
[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的第二个参数是一个回调函数,当它经过所有迭代时运行?
预期的输出:
3 done
1 done
2 done
All done!
奇怪的是,异步情况下有多少错误的答案!
可以简单地表明,检查索引没有提供预期的行为:
// INCORRECT
var list = [4000, 2000];
list.forEach(function(l, index) {
console.log(l + ' started ...');
setTimeout(function() {
console.log(index + ': ' + l);
}, l);
});
输出:
4000 started
2000 started
1: 2000
0: 4000
如果我们检查index === array。长度- 1,回调将在第一次迭代完成时被调用,而第一个元素仍然悬而未决!
要在不使用async等外部库的情况下解决这个问题,我认为最好的方法是保存列表的长度,并在每次迭代后递减。因为只有一个线程,我们确定没有竞争条件的机会。
var list = [4000, 2000];
var counter = list.length;
list.forEach(function(l, index) {
console.log(l + ' started ...');
setTimeout(function() {
console.log(index + ': ' + l);
counter -= 1;
if ( counter === 0)
// call your callback here
}, l);
});