2012-05-15 38 views
2

见与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]

回答

2

因为每个呼叫calls阵列引用相同i变量,认为这样的代码:

function fn() { 
    var i = 1; 
    setTimeout(function() { alert(i); }, 500); 
    i++; 
    i++; 
} 
fn(); 

此,当然,将输出代替,这是您的代码的相同问题,变量i在执行调用之前已更改;

为了避免这个问题,包循环与立即调用函数表达式创建一个新的范围,以存储i

for (var i = 0; i < 3; i++) { 
    (function(i) { 
     calls.push(function(cb) { inc(i, cb); }); 
    }(i)); 
} 
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)); 
} 
相关问题