3

最近、forループで延期されたjqueryの動作について質問しました。ここにリンク

実用的な回答を受け取りましたが、なぜそれが機能するのかわかりません。

次のコードがある場合:

function update(callbacks) {
    return $.Deferred(function(dfr) {
        setTimeout(function() {
            callbacks.success()
        }, 1000);
        dfr.resolve();
    }).promise();
}

function updateElements(deferreds) {
    for (var i = 0; i < 5; i++) {
        (function() {
            var index = i;
            deferreds.push(update({
                success: function() {
                    alert(index);
                }
            }));
        })();
    }
};

(function() {
    var deffereds = [];
    updateElements(deffereds);
    $.when.apply($, deffereds).then(function() {}, function() {});
})();​

0から4までの値を持つ5つのアラートウィンドウを返します。updateElementsメソッドを次のように変更した場合:

function updateElements(deferreds) {
    for (var i = 0; i < 5; i++) {
        var index = i;
        deferreds.push(update({
            success: function() {
                alert(index);
            }
        }));
    }
};

値が4のみの5つのアラートウィンドウを返します。誰かがこの行動を説明してもらえますか?違いがどこから来るのか理解するのに苦労しています。

ありがとう!

4

1 に答える 1

3

それを行う理由は、あなたがループを閉じたからです

(function() {
        var index = i;
        deferreds.push(update({
            success: function() {
                alert(index);
            }
        }));
})();

この自己実行ブロックは、外部値が渡されていないため、静的な値になります。リンクした回答と同様に、その値を渡す必要があります。IEFEの最後に値が指定されている主な違いに注意してください(すぐに)実行された関数式)。キャップで申し訳ありませんが、これは強調する必要があります。

(function(VALUE_ACCEPTED){
  //VALUE_ACCEPTED accepts the passed value of VALUE_PASSED
})(VALUE_PASSED)

あなたのコードがこれになるように:

function updateElements(deferreds) {
for (var i = 0; i < 5; i++) {
    (function(valueAccepted) { // valueAccepted = the passed in value from i
        var index = valueAccepted;
        deferreds.push(update({
            success: function() {
                alert(index);
            }
        }));
    })(i); // pass in i to valueAccepted
 }
};
于 2012-11-15T09:00:25.040 に答える