节点异步数组循环结果不符合预期
Node async array loop result not as expected
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 中的回调将被推送到回调队列。 Console.log("After loop");将被打印出来,然后调用堆栈将变空,然后所有回调将一个接一个地执行。但事实似乎并非如此。谁能解释一下?
谢谢。
问题是您在 forEach 中手动调用回调并将其结果传递给 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
方法中提供函数,就像我在上面的示例中提供的那样。
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 中的回调将被推送到回调队列。 Console.log("After loop");将被打印出来,然后调用堆栈将变空,然后所有回调将一个接一个地执行。但事实似乎并非如此。谁能解释一下?
谢谢。
问题是您在 forEach 中手动调用回调并将其结果传递给 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
方法中提供函数,就像我在上面的示例中提供的那样。