Comprenez comment le moteur ordonnance réellement le code synchrone, les microtâches et les macrotâches.
Ouvrir cette leçon dans KodokonJavaScript exécute votre code sur un seul thread, mais l'event loop n'est pas défini par ECMAScript : c'est la spécification HTML (et libuv côté Node.js) qui décrit son fonctionnement. Le moteur maintient une call stack pour le code en cours, une file de macrotâches (timers, I/O, événements) et une file de microtâches (Promise.prototype.then, queueMicrotask, MutationObserver). La règle d'or : après chaque macrotâche, la file des microtâches est vidée entièrement avant de rendre la main.
console.log("script start");
setTimeout(() => console.log("timeout"), 0);
Promise.resolve()
.then(() => console.log("promise 1"))
.then(() => console.log("promise 2"));
console.log("script end");
// script start, script end,
// promise 1, promise 2, timeoutLe script initial est lui-même une macrotâche : tant qu'il n'est pas terminé, rien d'autre ne s'exécute. Une fois la call stack vide, le moteur draine la file de microtâches, y compris celles ajoutées pendant le drainage. Ce détail explique pourquoi deux then chaînés s'exécutent avant un setTimeout(fn, 0) : chaque then replanifie une microtâche, et la file n'est jamais rendue tant qu'elle n'est pas vide.
setTimeout(() => console.log("macro 1"), 0);
setTimeout(() => console.log("macro 2"), 0);
queueMicrotask(() => {
console.log("micro 1");
queueMicrotask(() => console.log("micro 2"));
});
// micro 1, micro 2, macro 1, macro 2Le mot-clé await s'appuie sur ce mécanisme : il suspend la fonction async, restitue le contrôle à l'appelant, puis planifie la reprise comme une microtâche. Même await null provoque cette suspension, car la valeur est enveloppée dans une promesse déjà résolue. C'est pourquoi le code situé après un await ne s'exécute jamais de façon synchrone.
async function main() {
console.log("before await");
await null;
console.log("after await");
}
main();
console.log("sync code");
// before await, sync code, after awaitC en synchrone, planifie A via setTimeout(fn, 0) et B via Promise.resolve().then. Dans quel ordre les lettres s'affichent-elles ?await sous le capot ?