comportement différé de jQuery dans la boucle for

J’ai récemment posé une question sur le comportement de jQuery différé dans une boucle for. Lien ici

J’ai reçu une réponse qui fonctionne mais je ne comprends pas pourquoi cela fonctionne.

Si j’ai le code suivant:

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() {}); })();​ 

Il renvoie 5 fenêtres d’alerte avec les valeurs 0 à 4. Si je modifie la méthode updateElements en:

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

Il renvoie 5 fenêtres d’alerte avec la valeur 4 uniquement. Quelqu’un pourrait-il s’il vous plaît expliquer ce comportement? J’ai du mal à comprendre d’où vient la différence.

Merci!

La raison en est que vous avez fermé sur une boucle avec

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

Ce bloc à exécution automatique se transforme en valeur statique car aucune valeur externe n’a été transmise. Comme dans la réponse que vous avez liée, vous devez transmettre cette valeur. expression de fonction exécutée). Désolé pour les casquettes, mais cela mérite d’être souligné.

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

Pour que votre code devienne ceci:

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