La boucle d'événements est la boucle qui maintient l'ordre d'exécution (gestion des opérations asynchrones sans bloquer le thread principal) du code JavaScript.
Choses à savoir avant de plonger dans la boucle événementielle :
- Call Stack : c'est ici que JavaScript exécute notre code. Il suit une structure Last In, First Out (LIFO). Lorsqu'une fonction est appelée, un nouveau contexte d'exécution est créé et il est placé sur la pile. Lorsque la fonction se termine, elle est supprimée.
- MicroTasks Queue : File d'attente spéciale dédiée aux méthodes queueMicroTask, Promise, await rappels et MutationObserver (l'interface offre la possibilité de surveiller les modifications apportées à l'arborescence DOM).
- File d'attente MacroTasks : tous les autres rappels des API Web (setTimeout, setInterval, API DOM, fetch) entre dans la file d'attente des macroTasks.
Qu’est-ce que la boucle d’événements ?
C'est une boucle sans fin qui attend les tâches et les pousse dans la pile d'appels pour exécution. Étant donné que JavaScript est monothread, il maintient un ordre d'exécution pour gérer les deux opérations asynchrones synchrones en fonction de la priorité.
-
Code JS régulier : Le code synchrone s'exécute en premier et remplit la pile d'appels.
-
MicroTasks : Les tâches mises en file d'attente dans la file d'attente microTasks sont exécutées.
-
MacroTasks : Les tâches mises en file d'attente dans la file d'attente des macroTasks sont exécutées.
// Programmatic way of how the event loop processes tasks
while (true) {
// Step 1: Execute tasks in the call stack
while (!callStack.isEmpty()) {
const currentTask = callStack.pop();
currentTask(); // Executes the task
}
// Step 2: Process all microtasks
while (!microTasksQueue.isEmpty()) {
const microTask = microTasksQueue.shift();
callStack.push(microTask); // Push microtask to call stack for execution
}
// Step 3: Process one macrotask if available
if (!macroTasksQueue.isEmpty()) {
const macroTask = macroTasksQueue.shift();
callStack.push(macroTask); // Push macrotask to call stack for execution
}
// Break if there's nothing left to process
if (callStack.isEmpty() && microTasksQueue.isEmpty() && macroTasksQueue.isEmpty()) {
break;
}
}
Copier après la connexion
Passons en revue un exemple pour mieux comprendre le flux de travail
1. setTimeout(() => console.log(1), 2000);
2. Promise.resolve().then(() => {
3. console.log(2);
4. queueMicroTask(() => console.log(3));
5. });
6. Promise.resolve().then(() => {
7. console.log(4);
8. setTimeout(() => console.log(5));
9. });
10. setTimeout(() => console.log(6));
11. console.log(7);
// 7 2 4 3 6 5 1
Copier après la connexion
Supposons que nous ayons 2 files d'attente microTasks et macroTasks. Lorsque le code commence à s'exécuter,
-
() => console.log(1) est poussé dans la file d'attente macroTasks en 2000 ms.
-
() => { console.log(2); queueMicroTask(() => console.log(3)); }) est poussé dans la file d'attente microTasks.
-
() => { console.log(4); setTimeout(() => console.log(5)); }) est poussé dans la file d'attente microTasks.
-
() => console.log(6) est poussé dans la file d'attente macroTasks en 0 ms.
-
console.log(7) exécute et imprime 7 dans la console.
- Maintenant, la boucle d'événements vérifie la file d'attente microTasks pour les tâches et prend () => { console.log(2); queueMicroTask(() => console.log(3)); }) tâche et imprime 2 dans la console et pousse () => console.log(3) dans la file d'attente microTasks.
- Ensuite, la boucle d'événements vérifie la file d'attente microTasks et prend () => { console.log(4); setTimeout(() => console.log(5)); }) tâche et imprime 4 et pousses () => console.log(5) dans la file d'attente macroTasks en 0 ms.
- Encore une fois, la boucle d'événements vérifie la file d'attente microTasks et prend () => console.log(3)) et en imprime 3 dans la console.
- Puisque la file d'attente microTasks est maintenant vide, la boucle d'événements vérifie la macroTaskQueue et prend () => console.log(6) et imprime 6 dans la console.
- La boucle d'événement prend la tâche suivante () => console.log(5) à partir de la file d'attente macroTasks après vous être assuré qu'il n'y a aucune tâche dans la file d'attente microTasks et en imprime 5 dans la console .
- La boucle d'événement prend la tâche suivante () => console.log(1) à partir des macroTasks et imprime 1 dans la console.
Merci d'avoir lu ! J'espère que vous avez trouvé ce blog informatif et engageant. Si vous remarquez des inexactitudes ou avez des commentaires, n'hésitez pas à me le faire savoir.
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!