节点asynchronous数组循环结果不符合预期

function asyncForEach(array,cb) { array.forEach(function(i){ setTimeout(cb(i),0); }); } asyncForEach([1,2,3,4], function(i) { console.log(i); }); console.log("After loop"); 

上面的代码片段的结果,你会看到的是

 1 2 3 4 After loop 

我的预期是

 After loop 1 2 3 4 

我认为会发生的是函数asyncForEach将被添加到调用堆栈中,并且对于数组中的每个元素,setTimeout中的callback将被推送到callback队列。 Console.log(“After循环”); 将会被打印出来,然后调用堆栈将被清空,接下来所有的callback将被逐一执行。 但似乎并非如此。 谁能解释一下?

谢谢。

问题是你正在手动调用forEach中的callback,并将结果传递给setTimeout。

 setTimeout(cb(i), 0); // <-- you call cb(i) and pass its result into setTimeout 

你想要做的是这样的:

 setTimeout(cb, 0, i); 

或者更明确地说:

 setTimeout(function() { cb(i); }, 0); 

完整的例子:

 function asyncForEach(array,cb) { array.forEach(function(i){ setTimeout(cb, 0, i); }); } asyncForEach([1,2,3,4], function(i) { console.log(i); }); console.log("After loop"); 

要获得预期的输出,您需要进行以下更改:

 function asyncForEach(array,cb) { array.forEach(function(i){ setTimeout(function(){cb(i)},0); // CHANGE IS HERE }); } asyncForEach([1,2,3,4], function(i) { console.log(i); }); console.log("After loop"); 

基本上,当你在setTimeout函数内部提供一个函数调用(没有括号)的时候,你实际上正在调用这个函数。 为了在给定的超时后调度函数调用,你必须在setTimeout方法中提供函数,就像我在上面的例子中提供的那样。