for循环中的jQuery延迟行为

我最近在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() {}); })();​ 

它返回5个警报窗口,其值为0到4.如果我将updateElements方法更改为:

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

它返回5个警报窗口,其值仅为4。 有人可以解释一下这种行为吗? 我很难理解差异的来源。

谢谢!

这样做的原因是因为你已经关闭了一个循环

 (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 } };