Le code a un problème pour lequel la variable est écrite lorsque la fonction asynchrone est appelée. Comment peut-on le réparer?
Code:
for (x in files) { asynchronousFunction(var1, var2, function(){ console.log(x.someVaraible); }); }
Maintenant, le problème est que lorsque la fonction de rappel en fonction de la fonction asynchrone est appelée la variable x.files a été mise à jour pour la prochaine variable dans les fichiers du tableau json. Je veux que la variable contienne la valeur précédente.
Le nombre de variables dans la fonction de rappel ne peut pas être modifié, donc le nom de la variable ne peut pas être envoyé dans la fonction de rappel.
Le problème avec l'utilisation de variables «locales» dans javascript est que vos variables ont effectivement la portée de la fonction, plutôt que la portée du bloc – comme java et c # etc a
Une façon de contourner cela est d'utiliser let
qui a une portée de bloc, mais seuls firefox prend en charge ceci actuellement.
Donc, ce code fonctionnerait uniquement dans Firefox:
for (var x in files) { // This variable has BLOCK scope let file = files[x]; asynchronousFunction(var1, var2, function(){ console.log(file.someVaraible); }); }
Pour les autres navigateurs, l'alternative consiste à utiliser des fermetures
for (var x in files) { var file = files[x]; asynchronousFunction(var1, var2, (function(file){ return function() { console.log(file.someVaraible); }; })(file); }
Une autre façon que vous pouvez faire est d'utiliser map / forEach, en supposant que le type de données des fichiers est un tableau.
files.forEach(function(file) { asynchronousFunction(var1, var2, function(){ console.log(file.someVaraible); }); });
Si ce n'est pas un tableau, vous pouvez toujours utiliser cette technique
[].forEach.call(files, function(file) { asynchronousFunction(var1, var2, function(){ console.log(file.someVaraible); }); });
La manière plus complète d'écrire ceci est évidemment
Array.prototype.forEach.call(files, function(file) { // As before
Mais je me sens [].forEach
est plus agréable pour les yeux
Vous devez désinstaller le x
de la fermeture créée par la fonction de rappel. Réponse courte:
for (x in files) { asynchronousFunction(var1, var2, (function(y){ return function(){ console.log(y.someVaraible); } })(x) ); }
Pour une réponse plus longue et une explication, reportez-vous à ma réponse à une question précédente: expliquez l'utilisation des fermetures de JavaScript dans les boucles
Vous devez soit lier la variable à la définition de fonction, soit passer la variable dans la fonction. Je prendrais probablement une approche combinée, quelque chose comme:
for (x in files) { var local_x = x; var fn = function () { theRealFunction( local_x ); }; asynchronousFunction(var1, var2, fn); }
Bien que dans votre exemple, je n'aurais pas besoin d'appeler theRealFunction () comme étant une petite quantité de code (juste console.log).
X se fait itérer de sorte que lorsque la fonction de rappel est appelée, x sera la dernière fonction itérée de la boucle.
Correction en faisant de x
local comme ceci:
for (x in files) { (function() { var x = arguments[0]; asynchronousFunction(var1, var2, function() { console.log(x.someVaraible); }); }(x)); }