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]か?

4

2 に答える 2

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));
}
于 2012-05-15T06:00:33.180 に答える
2

配列内のすべての呼び出しは同じ変数を参照するため、次のコードを考えてみてください。callsi

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

これは確かに、1ではなく3を出力します。これはコードの同じ問題であり、呼び出しが実行される前に変数が変更されました。i

この問題を回避するには、forループをすぐに呼び出される関数式でラップして、新しいスコープを作成し、次の値を格納します。i

for (var i = 0; i < 3; i++) {
    (function(i) {
        calls.push(function(cb) { inc(i, cb); });
    }(i));
}
于 2012-05-15T06:02:10.937 に答える