"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > SetTimeout n'est pas la même chose que vous le pensez

SetTimeout n'est pas la même chose que vous le pensez

Publié le 2024-08-19
Parcourir:243

Lorsque les développeurs rencontrent pour la première fois setTimeout en JavaScript, cela semble souvent être un outil simple pour retarder l'exécution d'une fonction. Cependant, comprendre comment setTimeout interagit avec le runtime JavaScript et la boucle d'événements peut révéler un comportement inattendu, en particulier dans certaines conditions. Et ce n'est pas seulement setTimeout ; des complexités similaires surviennent également avec setInterval et d’autres fonctions asynchrones.

La boucle événementielle : un bref aperçu
JavaScript est monothread, ce qui signifie qu'il ne peut exécuter qu'un seul morceau de code à la fois. Malgré cela, la boucle d'événements permet à JavaScript d'effectuer des opérations non bloquantes. Il y parvient en déchargeant des tâches telles que des minuteries, des requêtes réseau ou des opérations d'E/S vers le navigateur ou l'API Node.js. Une fois ces tâches terminées, leurs fonctions de rappel sont remises en file d'attente dans la boucle d'événements pour exécution.

SetTimeout is Not the Same as You Think

Comment fonctionne setTimeout
Lorsque vous appelez setTimeout, vous demandez au moteur JavaScript d'exécuter une fonction après une période spécifiée. Cela se fait en ajoutant la fonction de rappel à la file d'attente de la boucle d'événements. Cependant, le délai spécifié est le temps minimum que le moteur doit attendre avant d'ajouter le rappel à la file d'attente, et non un temps d'exécution garanti. Voici comment cela fonctionne en détail :

  1. Appel initial : lorsque setTimeout est invoqué avec une fonction de rappel et un délai, le moteur JavaScript l'enregistre dans l'environnement API Web fourni par le navigateur ou Node.js.

  2. Timer : l'API Web démarre une minuterie pour le délai spécifié. Pendant cette période, la pile d'appels principale continue d'exécuter tout code synchrone qui suit l'appel setTimeout.

  3. Mise en file d'attente de rappel : une fois le délai écoulé, l'API Web n'exécute pas immédiatement le rappel. Au lieu de cela, il déplace la fonction de rappel vers la file d'attente des événements.

  4. Boucle d'événements : La boucle d'événements, qui surveille en permanence la pile d'appels et la file d'attente des événements, entre en jeu. Si la pile d'appels est vide, ce qui signifie qu'aucune tâche n'est en cours d'exécution, la boucle d'événements prend la première fonction de la file d'attente d'événements et la place sur la pile d'appels pour exécution.

  5. Exécution : la fonction de rappel est finalement exécutée lorsqu'elle atteint le sommet de la pile d'appels.

Il est important de noter que si la pile d'appels est occupée par d'autres tâches à l'expiration du délai, il peut y avoir des délais supplémentaires avant l'exécution de la fonction de rappel. En effet, la boucle d'événements doit attendre que la pile d'appels soit vide avant de pouvoir traiter la fonction de rappel à partir de la file d'attente d'événements.

SetTimeout is Not the Same as You Think


Le problème de blocage
Un malentendu courant consiste à supposer que setTimeout exécutera toujours le rappel après le délai exact spécifié. Si la boucle d'événement est bloquée par du code synchrone, comme une boucle infinie ou un calcul de longue durée, le rappel ne sera pas exécuté tant que la boucle d'événement n'est pas libre.

Considérez le scénario suivant :

console.log('Program started at: '   new Date().toLocaleTimeString());

const programStartTime = Date.now();

function blockExecutionForThirtySeconds() {
  while (true) {
    const currentTime = Date.now();
    if (currentTime - programStartTime > 30000) {
      console.log('Blocking execution completed after 30 seconds...');
      return true;
    }
  }
}

console.log('Setting setTimeout for 1 second.');
setTimeout(() => {
  console.log('setTimeout executed after 30 seconds instead of 1 second: '   new Date().toLocaleTimeString());
}, 1000);

blockExecutionForThirtySeconds();

Dans cet exemple, la fonction blockExecutionForThirtySeconds bloque la boucle d'événement avec une boucle infinie qui s'exécute pendant 30 secondes. Même si setTimeout est configuré pour s'exécuter après 1 seconde, il ne s'exécutera qu'après la fin de blockExecutionForThirtySeconds, soit après 30 secondes.

SetTimeout is Not the Same as You Think

Implications dans le monde réel
Comprendre ce comportement est crucial pour les développeurs, en particulier lors de l'écriture de code impliquant des délais d'attente, des intervalles ou un traitement asynchrone. Une mauvaise compréhension du fonctionnement de setTimeout peut entraîner des problèmes de performances et des bogues difficiles à retracer. Si un morceau de code effectue des calculs lourds ou des tâches de longue durée et bloque la boucle d'événements, tous les rappels setTimeout, résolutions de promesses et autres opérations asynchrones seront retardés jusqu'à ce que la boucle d'événements soit libre.

Conclusion
setTimeout est un outil puissant en JavaScript pour retarder l'exécution du code, mais il est important d'en comprendre les nuances. Le délai spécifié est le temps d'attente minimum avant que la fonction puisse être mise en file d'attente pour exécution. Le temps d'exécution réel dépend de l'état de la boucle d'événements. La maîtrise des opérations asynchrones et de la gestion des boucles d'événements est essentielle pour écrire des applications JavaScript efficaces et réactives.

Déclaration de sortie Cet article est reproduit sur : https://dev.to/mrrishimeena/settimeout-is-not-the-same-as-you-think-44ep?1 En cas de violation, veuillez contacter [email protected] pour supprimer il
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3