几天来我一直在努力解决这个问题,但我就是想不出一种优雅的方式来处理它。这就是问题所在。
我正在运行一个 forEach 循环,我需要知道一切何时完成。由于 forEach 循环是阻塞的,因此在 forEach 循环之后删除 a 应该很容易console.log
,它将在 forEach 循环完成时运行。但是,如果 forEach 循环中有任何不同步的函数,整个系统很快就会崩溃,除了非常奇怪的 hacky 计数器和 if 语句之外,我无法知道循环的内容何时完成。我的问题是在 javascript 中是否有一种优雅的方式来处理这种情况。
这里有几个例子:
在这种情况下,forEach 循环运行得非常好,因为循环中的所有内容都是同步的。
[1,2,3].forEach(function(num){
console.log("we're on " + num);
});
console.log('done counting!')
//=> we're on 1
//=> we're on 2
//=> we're on 3
//=> done counting!
这是我们开始遇到问题的地方,作为一个基本示例:
[1,2,3].forEach(function(num){
setTimeout(function(){ console.log(num) }, 200);
});
console.log('done counting!');
//=> done counting!
//=> we're on 1
//=> we're on 2
//=> we're on 3
尽管发生这种情况确实是有道理的,但我现在手头有一个不幸的问题,当我们完成计数时我需要回调,而且除了像这样恶心的东西之外,我没有其他顺利的方法:
var counter = 0;
var numbers = [1,2,3]
var log_number = function(num){
console.log("we're on " + num);
counter++;
if (counter == numbers.length) {
console.log("done counting!")
}
}
numbers.forEach(function(num){
setTimeout(log_number(num), 200);
});
//=> we're on 1
//=> we're on 2
//=> we're on 3
//=> done counting!
天哪,这是一个非常多的开销。有没有更顺畅的方法来实现这一点?我已经检查了承诺、延迟和序列,但我还没有真正能够以一种更简洁的方式实现它们中的任何一个:(
需要明确的是,我的问题并不是 setTimeout,它通常在同步函数中运行异步函数——这只是最简单的例子。