使用async查看以下nodejs代码:
var async = require('async');
function inc(n, cb) {
setTimeout(function() {
cb(null, n+1);
},1000);
};
var calls = [];
for(i=0;i<3;i++) {
calls.push(function(cb){
inc(i, cb);
});
}
async.parallel(calls, function(err, results) {
console.log(results);
});
打印:
[4, 4, 4]
我不明白为什么结果不是[1, 2, 3]
?
答案 0 :(得分:2)
for(i=0;i<3;i++) {
calls.push(function(cb){
inc(i, cb);
});
}
函数在for
循环结束后执行;当时,i
等于3
。
你应该在这里使用另一个闭包。例如:
for(i=0;i<3;i++) {
calls.push(function (i) {
return function (cb) {
inc(i, cb);
}
}(i));
}
答案 1 :(得分:2)
因为calls
数组中的每个调用都引用相同的i
变量,请考虑以下代码:
function fn() {
var i = 1;
setTimeout(function() { alert(i); }, 500);
i++;
i++;
}
fn();
这当然会输出 3 而不是 1 ,这与您的代码相同,变量i
在之前发生了变化致电执行;
要避免此问题,请使用立即调用的函数表达式包装 for 循环,以创建一个新范围来存储i
for (var i = 0; i < 3; i++) {
(function(i) {
calls.push(function(cb) { inc(i, cb); });
}(i));
}