2012-05-15 31 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)); 
} 
相關問題