Maison >interface Web >js tutoriel >Pourquoi cette boucle JavaScript produit-elle des résultats inattendus avec « setTimeout » ?

Pourquoi cette boucle JavaScript produit-elle des résultats inattendus avec « setTimeout » ?

DDD
DDDoriginal
2024-12-15 20:37:10129parcourir

Why Does This JavaScript Loop Produce Unexpected Results with `setTimeout`?

Exécution asynchrone de boucles et setTimeout

Considérez le script suivant :

for (var i = 1; i <= 2; i++) {
  setTimeout(function () { alert(i) }, 100);
}

Contrairement aux valeurs attendues de 1 et 2, le le script génère 3 deux fois. Ce comportement est dû à la nature asynchrone de la boucle d'événements JavaScript.

Comprendre la boucle d'événements JavaScript

La boucle d'événements JavaScript traite l'exécution du code en deux étapes : une pile synchrone et une file d'attente asynchrone. Le code synchrone s'exécute immédiatement dans la pile, tandis que le code asynchrone, tel que setTimeouts, est placé dans la file d'attente pour être exécuté ultérieurement.

Le problème avec la boucle

Dans le script, le rappel setTimeout la fonction utilise la variable i. Cependant, i est partagé entre toutes les itérations de la boucle, et au moment où le rappel s'exécute, il fait toujours référence à la valeur finale de 2. Par conséquent, 3 est imprimé les deux fois.

L'approche correcte

Pour garantir que les valeurs consécutives sont imprimées, créez une copie distincte de i pour chaque fonction de rappel. Ceci peut être réalisé en utilisant une fermeture de fonction, comme indiqué ci-dessous :

function doSetTimeout(i) {
  setTimeout(function () {
    alert(i);
  }, 100);
}

for (var i = 1; i <= 2; ++i) doSetTimeout(i);

Dans ce script, la fonction doSetTimeout capture la valeur de i en tant que variable locale pour sa fermeture, garantissant que chaque fonction de rappel utilise le bon valeur.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn