Lorsque vous travaillez avec des fonctions asynchrones dans une boucle for JavaScript, il est possible de rencontrer des problèmes liés à l'exécution asynchrone et à la portée des variables.
Considérez le code suivant :
for (var i = 0; i < list.length; i++) { mc_cli.get(list[i], function (err, response) { do_something(i); }); }
Dans cet exemple, mc_cli.get est une fonction asynchrone qui appelle la fonction de rappel lorsque l'opération est terminée. Cependant, comme le rappel est asynchrone, il peut être exécuté après la fin de la boucle for, ce qui peut entraîner un comportement incorrect.
Un autre problème survient lors de l'utilisation de la fonction do_something à partir du rappel. Puisque la variable i est une variable de boucle, sa valeur change tout au long de l'exécution de la boucle. Par conséquent, do_something(i) utilisera toujours la dernière valeur de i dans la boucle, ce qui n'est pas le comportement souhaité.
Pour résoudre ces problèmes, une approche courante consiste à utiliser des fermetures. Les fermetures vous permettent de créer une nouvelle portée autour d'une variable, garantissant que sa valeur reste cohérente tout au long de l'opération asynchrone. Cependant, dans l'exemple fourni, les fermetures ne sont pas implémentées correctement.
Une implémentation correcte serait de créer une fonction interne dans la boucle qui a accès à la valeur actuelle de i:
for (var i = 0; i < list.length; i++) { (function (i) { mc_cli.get(list[i], function (err, response) { do_something(i); }); })(i); }
Dans ce cas, la fonction interne a sa propre portée et peut accéder à la valeur de i depuis la boucle externe. Cependant, il est important de noter que la boucle externe doit être terminée avant que mc_cli.get ne soit appelé, sinon vous risquez toujours de rencontrer des problèmes.
Vous pouvez également utiliser la méthode forEach sur le tableau, qui fournit l'élément de liste. et l'index dans le rappel, éliminant complètement le besoin de fermetures :
list.forEach(function (listItem, index) { mc_cli.get(listItem, function (err, response) { do_something(index); }); });
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!