2
var data = [{offset: 2000, str:'foo'}, {offset: 4000, str:'bar'}];

for (var i=0; i<data.length; i++) {
    var x = data[i];
    setTimeout(function(){printStuff(x.str)}, x.offset);
}

function printStuff(str) {
    console.log(str);
}

私はprintStuff('foo')2000ミリ秒のオフセットとprintStuff('bar')4000ミリ秒のオフセットで取得することを期待していましたが、代わりに両方の時間で「バー」を出力します。何が起こっているのかわかりません。助けてください。

4

3 に答える 3

3

これを行う :

for (var i = 0; i < data.length; i++) {
    (function (x) {
        setTimeout(function () {
            printStuff(x.str)
        }, x.offset);
    })(data[i]);
}

問題は、関数が呼び出されたときにクロージャでxが変更されたことです。

于 2012-07-06T14:19:52.063 に答える
2

無料でクロージャを提供する関数反復を使用できます。

data.forEach( function( x ) {
      setTimeout( printStuff.bind(null, x.str), x.offset );
});

oldIEサポートが必要な場合のすべてのシム:

forEach

練る

于 2012-07-06T14:24:03.560 に答える
0

setTimeoutコードの実行の継続をブロックしないため、ループが完了し、setTimeoutコールバックが実行されるまでに、「x」の最新の値がdata配列の2番目のオブジェクトになります。

于 2012-07-06T14:24:08.070 に答える