1

基本的な問題が発生したとき、私はちょうどいくつかのテストを書いていました。テストフレームワークのベアスケルトンを書きました。最初にすべてのテスト (それらのコールバック) を配列に収集し、その後別のループで実行します。しかし、これは

//test.js
var testArray = [
    {
    n : 1,
    d : 'text1'
    },
    {
    n : 2,
    d : 'text2'
    }
];

var cbs = [];
function fnWithCallback(d, cb) {
    console.log('d=('+d+')');
    cbs.push(cb);
}

for(var i=0; i < testArray.length; i++) {
    var v = testArray[i];

    fnWithCallback(v.d, function() {
    console.log('v=('+v.n+'), i=('+i+')');
    });
}

for(var j=0; j < cbs.length; j++) {
    cbs[j]();
}

このサンプルを実行すると、次のようになります。

> node test.js
d=(text1)
d=(text2)
v=(2), i=(2)
v=(2), i=(2)

つまり、コールバックでは、'v' が最後の配列の最後の要素に割り当てられ、'i' が最後の状態に割り当てられており、コールバックが '作成' されて 'fnWithCallback' 関数に渡されたときの状態ではありません。ただし、「d」はコールバック内で出力されるため、「fnWithCallback」が呼び出されたときに要素の値が保持されます。

ループを「アンループ」しても役に立ちません。

var v = testArray[0];

fnWithCallback(v.d, function() {
    console.log('v=('+v.n+')');
});

v = testArray[1];

fnWithCallback(v.d, function() {
    console.log('v=('+v.n+')');
});

同じ動作になります。

誰かがこれを説明して解決策を提供できますか?

4

1 に答える 1

1

クロージャーを使用する

fnWithCallback(v.d, (function(v,i){
    return function() {
        console.log('v=('+v.n+'), i=('+i+')');
    };
})(v,i)));
于 2012-04-17T14:35:37.507 に答える