Les microtâches en JavaScript
La file des microtâches est un composant clé du modèle d'exécution asynchrone en JavaScript, prioritaire sur les macrotâches.
En JavaScript, la file des microtâches est un composant essentiel du modèle d'exécution asynchrone. Elle priorise certains rappels (callbacks), garantissant qu'ils s'exécutent après le script en cours, mais avant que la boucle d'événements ne reprenne d'autres tâches telles que le rendu ou la gestion des événements utilisateur. Ce guide propose une exploration approfondie de l'utilisation efficace de la file des microtâches pour améliorer vos applications JavaScript.
Comprendre la boucle d'événements et la file des microtâches
Le moteur JavaScript utilise une boucle d'événements qui gère l'exécution des scripts, permettant des opérations non bloquantes. La file des microtâches fait partie de cette boucle d'événements. Elle est utilisée spécifiquement pour les promesses (voir JavaScript : les Promises) et d'autres opérations comme queueMicrotask, afin qu'elles soient traitées à la fin de l'exécution courante de la boucle d'événements JavaScript, avant la phase de rendu.
Il existe deux files distinctes à garder à l'esprit :
- La file des microtâches contient les callbacks issus des promesses résolues/rejetées et de
queueMicrotask(). Après chaque tâche, le moteur vide cette file entièrement avant de faire quoi que ce soit d'autre. - La file des macrotâches (parfois appelée file des tâches) contient les callbacks issus de
setTimeout,setInterval, des E/S et des événements UI. Un seul macrotâche s'exécute par itération de la boucle.
La règle fondamentale : lorsque le code synchrone en cours se termine, le moteur vide d'abord toute la file des microtâches, puis seulement il passe à la macrotâche suivante. C'est pourquoi un callback de promesse s'exécute toujours avant un callback setTimeout(…, 0) planifié plus tôt. Pour une vue d'ensemble complète de l'interaction entre ces files, voir Boucle d'événements : microtâches et macrotâches.
Exemple : Promesse basique
Dans cet exemple, la console affiche d'abord 'Script end', puis 'Promise resolved'. Cela illustre comment JavaScript reporte la résolution des promesses à la file des microtâches.
Comment fonctionne la file des microtâches ?
La file des microtâches exécute les tâches planifiées en tant que microtâches. Cela inclut les opérations provenant de :
- Promises
- Object.observe (déprécié)
- MutationObserver
- L'API
queueMicrotask()
Chacune de ces microtâches est traitée entièrement avant de passer à la suivante ou avant tout rendu ou autre macrotâche.
Planifier des microtâches
Vous pouvez planifier directement des microtâches en utilisant la fonction queueMicrotask. Cette fonction prend un callback et l'ajoute à la file des microtâches. Comme vous pouvez le constater, la file s'exécute après que toutes les autres tâches sont terminées.
Microtâche vs. macrotâche : pourquoi une Promise l'emporte sur setTimeout(0)
Une source fréquente de confusion est de comprendre pourquoi un callback de promesse s'exécute avant un callback setTimeout(…, 0), même lorsque le timer a été planifié en premier. La réponse tient à la règle ci-dessus : une fois que le code synchrone est terminé, le moteur vide toute la file des microtâches avant de toucher à la file des macrotâches, où vivent les callbacks de setTimeout. Même un timer à délai zéro doit attendre.
La sortie est toujours :
1: synchronous start
2: synchronous end
3: promise (microtask)
4: setTimeout (macrotask)Les lignes 1 et 2 s'exécutent en premier car le code synchrone ne cède jamais la main. Ensuite, la file des microtâches est vidée (le callback de la promesse), et ce n'est qu'après cela que la macrotâche suivante — le callback setTimeout — obtient son tour. Pour en savoir plus sur les timers, consultez Planification : setTimeout et setInterval.
Ordre d'exécution au sein de la file des microtâches
Les microtâches elles-mêmes s'exécutent dans l'ordre où elles ont été ajoutées à la file (FIFO). Mélanger des callbacks .then() avec queueMicrotask() le rend évident — les deux alimentent la même file, donc le résultat est simplement premier entré, premier sorti :
Cela affiche start, end, promise 1, queueMicrotask, promise 2. Notez qu'une microtâche planifiée par une autre microtâche est ajoutée à la même file et s'exécute dans le même cycle de vidage — avant tout rendu ou macrotâche. C'est précisément ce qui permet à des boucles de microtâches incontrôlées d'affamer le reste de la page.
Applications pratiques des microtâches
Les microtâches sont particulièrement utiles dans les applications web complexes pour les tâches nécessitant une attention immédiate après le script en cours, mais avant que le système ne gère d'autres événements ou ne réaffiche l'interface utilisateur.
Scénario : traitement de données en temps réel
Considérez un scénario où des données en temps réel provenant d'un serveur doivent être traitées sans interrompre l'expérience utilisateur :
Cet exemple illustre la récupération asynchrone de données, leur traitement, et la planification d'une mise à jour de l'interface dans la file des microtâches.
Gestion efficace des erreurs dans les Promises
Gérer efficacement les erreurs dans le code asynchrone est essentiel. Utiliser la file des microtâches avec la gestion des erreurs des promesses garantit que les erreurs sont traitées immédiatement après la logique de résolution de la promesse, mais avant d'autres tâches non liées.
Bonnes pratiques pour l'utilisation de la file des microtâches
- Ordonnancement des tâches : Comprendre quand utiliser les microtâches pour garantir le séquençage correct des opérations.
- Éviter la famine : S'assurer que la file des microtâches ne reçoit pas continuellement de nouvelles tâches, ce qui empêcherait les macrotâches telles que les mises à jour de l'interface de s'exécuter.
- Débogage : Tracer et déboguer l'exécution des microtâches pour éviter les comportements inattendus dans le code asynchrone.
Conclusion
Maîtriser la file des microtâches en JavaScript est essentiel pour développer des applications avancées et réactives. En tirant efficacement parti de ce composant puissant du modèle d'exécution JavaScript, les développeurs peuvent garantir des interactions plus fluides et non bloquantes, ainsi qu'une meilleure expérience utilisateur. Cette exploration fournit les connaissances fondamentales et les compétences pratiques pour utiliser la file des microtâches efficacement dans tout projet JavaScript.