Boucle d'événements JavaScript, microtâches et macrotâches
JavaScript est un langage puissant souvent utilisé dans le développement web, et l'un de ses concepts fondamentaux est la gestion des opérations asynchrones. Pour rendre ce concept plus clair pour les débutants, nous explorerons la boucle d'événements (Event Loop), ainsi que les rôles des microtâches et des macrotâches, accompagnés d'exemples simples pour démontrer comment JavaScript gère différentes opérations.
Aperçu simplifié de la boucle d'événements
La boucle d'événements est un mécanisme que JavaScript utilise pour gérer l'exécution du code, des événements et des messages de manière efficace. Voici une façon simple de la visualiser :
- Pile (Stack) : C'est là que votre code JavaScript commence à s'exécuter, de haut en bas, comme des blocs empilés.
- Tas (Heap) : Considérez-le comme le magasin de mémoire pour les objets créés par votre code.
- File d'attente (Queue) : JavaScript utilise en réalité deux files d'attente distinctes : une file d'attente de macrotâches (pour les minuteurs, les événements UI et les E/S) et une file d'attente de microtâches (pour les Promises et
queueMicrotask).
La boucle d'événements vérifie continuellement la pile pour voir s'il y a quelque chose à exécuter. Si la pile est vide, elle vérifie d'abord la file d'attente des microtâches. Une fois cette file vide, elle examine la file d'attente des macrotâches pour voir s'il y a des tâches en attente à exécuter. Ce cycle permet à JavaScript d'effectuer des tâches comme les mises à jour de l'interface utilisateur, de gérer les interactions utilisateur ou de récupérer des données en arrière-plan sans bloquer le thread principal.
Voici un exemple simple pour expliquer le fonctionnement de la boucle d'événements JavaScript, en mettant particulièrement l'accent sur la gestion des événements asynchrones avec setTimeout :
Dans cet exemple :
console.log('Start');est exécuté en premier, affichant « Start » dans la console.setTimeoutplanifie une fonction de rappel à exécuter après 1000 millisecondes (1 seconde). Cependant, cela ne bloque pas l'exécution du code suivant.console.log('End');est exécuté immédiatement après la planification du délai, affichant « End » dans la console.- Une fois le thread principal libre et le délai d'une seconde écoulé, la boucle d'événements vérifie d'abord la file d'attente des microtâches. Si elle est vide, elle passe à la file d'attente des macrotâches, trouve le rappel de
setTimeoutet l'exécute, affichant « Timeout Callback » dans la console.
Cette séquence démontre efficacement comment la boucle d'événements JavaScript gère les tâches et comment elle utilise la file d'attente des tâches pour gérer les événements asynchrones comme les délais. Le rappel setTimeout est un exemple de macrotâche qui est traitée après la fin du script en cours d'exécution et de toutes les autres tâches en attente. Cela garantit que le code synchrone s'exécute immédiatement sans attendre le code asynchrone (comme les opérations d'E/S ou les minuteurs), ce qui maintient l'application réactive.
Microtâches vs. Macrotâches
Qu'est-ce que les macrotâches ?
Les macrotâches sont des blocs de tâches qui incluent des éléments tels que :
setTimeout: Retarde l'exécution d'un morceau de code jusqu'à ce que le délai spécifié soit écoulé.setInterval: Exécute continuellement un morceau de code à chaque intervalle spécifié.- Événements et opérations d'E/S : Comme un clic sur un bouton ou le chargement de données depuis une source externe.
Chaque macrotâche est terminée avant de passer à la suivante.
Qu'est-ce que les microtâches ?
Les microtâches sont de petites tâches qui doivent être effectuées sans interruption. Elles incluent :
- Résolutions de Promises : Actions que vous promettez d'effectuer lorsqu'une autre tâche est terminée.
- Fonction
queueMicrotask: Ajoute directement des microtâches.
Les microtâches sont traitées plus rapidement et plus fréquemment que les macrotâches. Elles sont traitées après chaque macrotâche et avant que le moteur JavaScript ne passe à la macrotâche suivante.
Exemples de code concrets
Exemple 1 : Utilisation de setTimeout comme macrotâche
Imaginez que vous souhaitiez afficher un message sur une page web après 2 secondes.
Explication : Ce code configure un minuteur qui attend 2 secondes avant de s'exécuter. Il modifie ensuite le texte d'un élément de la page (nécessite un environnement navigateur). Il s'agit d'une macrotâche car elle est planifiée pour s'exécuter indépendamment du flux principal du programme.
Exemple 2 : Utilisation de Promises comme microtâches
Disons que vous souhaitez afficher un message juste après une tâche rapide, comme la mise à jour d'un statut.
Explication : Ce code crée une promesse qui se résout immédiatement, puis exécute immédiatement le code à l'intérieur de .then() une fois la pile vide. Il s'agit d'une microtâche car c'est une petite tâche qui doit s'exécuter juste après le code en cours.
En savoir plus sur la priorité des micro et macrotâches
En JavaScript, comme nous l'avons appris, les tâches au sein de la boucle d'événements sont classées comme microtâches ou macrotâches, chacune ayant une priorité spécifique. Les microtâches incluent des opérations comme le traitement des Promises, et elles ont toujours une priorité plus élevée. Cela signifie qu'après la fin du script en cours, le moteur JavaScript traitera toutes les microtâches en attente avant de commencer toute macrotâche, comme les délais ou les gestionnaires d'événements.
Voici un exemple simple pour voir cela en action :
Sortie attendue :
Start
End
Promise 1
Promise 2
Timeout 1
Timeout 2Cette séquence montre comment les microtâches (résolutions de Promises) sont exécutées immédiatement après le code synchrone, même avant les macrotâches planifiées pour le même moment. Cette priorisation garantit que les tâches critiques, comme la mise à jour des données, sont terminées dès que possible.
Conclusion
Comprendre la boucle d'événements, ainsi que les microtâches et les macrotâches, peut grandement améliorer votre capacité à écrire du JavaScript efficace. En sachant comment et quand JavaScript exécute votre code, vous pouvez créer des applications plus réactives et performantes. L'essentiel est d'utiliser les macrotâches pour les grandes tâches moins urgentes, et les microtâches pour les petites tâches immédiates. Ce guide devrait vous aider à saisir les bases et à commencer à appliquer ces concepts dans vos propres projets !
Pratique
En JavaScript, que se passe-t-il lorsqu'une promesse se résout et qu'un gestionnaire `.then()` est attaché ?