Traitement asynchrone au sein d'une boucle JavaScript for : préserver les valeurs d'itération de la boucle
Dans la programmation asynchrone, les opérations sont initiées et poursuivent leur exécution indépendamment du fil conducteur. Cela peut entraîner des problèmes lors de la tentative de synchronisation des résultats d'opérations asynchrones avec la progression d'un flux de contrôle synchrone, tel qu'une boucle for.
Considérez la boucle for suivante :
let i; let j = 10; for (i = 0; i < j; i++) { asynchronousProcess(callbackFunction() { alert(i); }); }
L'objectif est d'afficher une série d'alertes affichant les nombres de 0 à 10. Cependant, en raison de la nature asynchrone de la fonction asynchronousProcess, la fonction de rappel est déclenchée après le la boucle a effectué plusieurs itérations. Par conséquent, les valeurs d'alerte ne sont pas affichées dans l'ordre prévu.
Solution : Utiliser des fermetures de fonctions pour capturer les valeurs de boucle
Pour résoudre ce problème, il est nécessaire pour garantir que chaque itération de la boucle a une valeur unique de i lorsque la fonction de rappel est appelée. Ceci peut être réalisé en capturant la variable de boucle dans une fermeture de fonction.
Cela peut être accompli en utilisant une IIFE (Immediately Invoked Function Expression) :
for (var i = 0; i < j; i++) { (function(cntr) { asynchronousProcess(function() { alert(cntr); }); })(i); }
Dans cet exemple, la valeur de i est transmis à l'IIFE en tant que cntr, et la fermeture de fonction garantit que chaque itération a sa propre valeur unique de i.
Alternativement, vous pouvez créer une fonction externe qui accepte la variable de boucle comme paramètre :
function logIndex(index) { console.log(index); } for (var i = 0; i < j; i++) { asynchronousProcess(logIndex.bind(null, i)); }
Utilisation des déclarations de variables ES6 let
Avec l'introduction d'ES6, il est possible de déclarer des variables de boucle en utilisant let , qui crée des variables de portée bloc. Cela fournit un moyen pratique de garantir que chaque itération de la boucle a sa propre valeur unique de i :
for (let i = 0; i < j; i++) { asynchronousProcess(function() { alert(i); }); }
Remarque :
Il est important de noter que chacune de ces solutions crée une copie de la variable de boucle au moment de la fermeture de la fonction ou de la déclaration de la variable. Si la variable de boucle est modifiée une fois l'opération asynchrone terminée, ces copies ne refléteront pas la valeur mise à jour.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!