Étant donné que javascript dans un navigateur est à thread unique (sauf pour les webworkers qui ne sont pas impliqués ici) et qu'un thread d'exécution de javascript s'exécute jusqu'à la fin avant qu'un autre puisse s'exécuter, votre déclaration:
while(flag==false) {}
fonctionnera simplement pour toujours (ou jusqu'à ce que le navigateur se plaint d'une boucle javascript non réactive), la page semblera bloquée et aucun autre javascript n'aura jamais la possibilité de s'exécuter, la valeur de l'indicateur ne pourra donc jamais être modifiée.
Pour un peu plus d'explications, Javascript est un langage événementiel . Cela signifie qu'il exécute un morceau de Javascript jusqu'à ce qu'il renvoie le contrôle à l'interpréteur. Ensuite, seulement lorsqu'il revient à l'interpréteur, Javascript récupère l'événement suivant de la file d'attente d'événements et l'exécute.
Toutes les choses comme les minuteries et les événements réseau passent par la file d'attente des événements. Ainsi, lorsqu'une minuterie se déclenche ou qu'une requête réseau arrive, elle n'interrompt jamais le Javascript en cours d'exécution. Au lieu de cela, un événement est placé dans la file d'attente d'événements Javascript, puis, lorsque le Javascript en cours d'exécution se termine, l'événement suivant est extrait de la file d'attente d'événements et il est exécuté à son tour.
Ainsi, lorsque vous effectuez une boucle infinie telle que while(flag==false) {}
, le Javascript en cours d'exécution ne se termine jamais et donc l'événement suivant n'est jamais extrait de la file d'attente d'événements et donc la valeur de flag
ne change jamais. La clé ici est que Javascript n'est pas piloté par interruption . Lorsqu'un minuteur se déclenche, il n'interrompt pas le Javascript en cours d'exécution, exécute un autre Javascript et laisse le Javascript en cours d'exécution continuer. Il est simplement placé dans la file d'attente d'événements en attendant que le Javascript en cours d'exécution soit terminé pour s'exécuter à son tour.
Ce que vous devez faire est de repenser le fonctionnement de votre code et de trouver une manière différente de déclencher le code que vous souhaitez exécuter lorsque la flag
valeur change. Javascript est conçu comme un langage événementiel. Donc, ce que vous devez faire est de déterminer les événements pour lesquels vous pouvez enregistrer un intérêt afin que vous puissiez soit écouter l'événement qui pourrait provoquer le changement du drapeau et vous pouvez examiner le drapeau sur cet événement ou vous pouvez déclencher votre propre événement à partir de quel que soit le code qui pourrait changer l'indicateur ou vous pouvez implémenter une fonction de rappel que quel que soit le code qui change, cet indicateur peut appeler votre rappel chaque fois que le morceau de code responsable de la modification de la valeur de l'indicateur changerait sa valeur en true
, il appelle simplement la fonction de rappel et donc votre code qui veut s'exécuter lorsque l'indicateur est défini surtrue
arrivera à fonctionner au bon moment. C'est beaucoup plus efficace que d'essayer d'utiliser une sorte de minuterie pour vérifier constamment la valeur de l'indicateur.
function codeThatMightChangeFlag(callback) {
// do a bunch of stuff
if (condition happens to change flag value) {
// call the callback to notify other code
callback();
}
}
jQuery.Deferred
,Q
,async
...