11
Programmation Asynchrone
Event Loop, Callbacks & Timers
JavaScript est single-threaded mais peut gérer des opérations asynchrones grâce à l'Event Loop. Comprendre ce mécanisme est essentiel.
🔄 L'Event Loop
L'Event Loop permet à JavaScript d'exécuter du code asynchrone sans bloquer le thread principal.
📊 Architecture de l'Event Loop
📚 Call Stack
Pile d'exécution (LIFO)
main()
⏱️ Task Queue (Macrotasks)
setTimeout, setInterval, I/O
Vide
⚡ Microtask Queue
Promises, queueMicrotask
Vide
Ordre d'exécution :
1️⃣ Call Stack : Code synchrone
2️⃣ Microtasks : Promises (priorité haute)
3️⃣ Macrotasks : setTimeout, setInterval (priorité basse)
1️⃣ Call Stack : Code synchrone
2️⃣ Microtasks : Promises (priorité haute)
3️⃣ Macrotasks : setTimeout, setInterval (priorité basse)
⏱️ Timers : setTimeout & setInterval
// setTimeout : Exécute UNE FOIS après délai
setTimeout(() => {
console.log('Exécuté après 1 seconde');
}, 1000);
// setInterval : Exécute RÉPÉTITIVEMENT
const intervalId = setInterval(() => {
console.log('Toutes les 2 secondes');
}, 2000);
// ⚠️ TOUJOURS nettoyer les intervals !
clearInterval(intervalId);
// Pattern : Auto-nettoyage
const id = setInterval(() => {
console.log('Tick');
if (condition) clearInterval(id);
}, 1000);
// setTimeout avec 0ms : Reporte à la prochaine itération
setTimeout(() => console.log('Async'), 0);
console.log('Sync'); // S'exécute AVANT
// Output: "Sync" puis "Async"
😱 Callback Hell vs Solutions Modernes
❌ Callback Hell (Pyramid of Doom)
getData(function(a) {
getMoreData(a, function(b) {
getMoreData(b, function(c) {
getMoreData(c, function(d) {
getMoreData(d, function(e) {
// 😱 Illisible !
});
});
});
});
});
✅ Async/Await (Moderne)
async function fetchData() {
const a = await getData();
const b = await getMoreData(a);
const c = await getMoreData(b);
const d = await getMoreData(c);
const e = await getMoreData(d);
// ✅ Lisible, séquentiel
}
🎮 Playground : Ordre d'Exécution
Prédisez l'ordre d'exécution, puis vérifiez !
console.log('1: Sync');
setTimeout(() => console.log('2: Macro (setTimeout)'), 0);
Promise.resolve().then(() => console.log('3: Micro (Promise)'));
console.log('4: Sync');
queueMicrotask(() => console.log('5: Micro (queueMicrotask)'));
// Quel est l'ordre d'affichage ?
Cliquez sur Exécuter pour voir l'ordre
⚡ Microtasks vs Macrotasks
| Type | Exemples | Priorité |
|---|---|---|
| Microtasks | Promise.then, queueMicrotask,
MutationObserver
|
Haute |
| Macrotasks | setTimeout, setInterval,
setImmediate, I/O
|
Basse |
Best Practice : Les Microtasks (Promises) s'exécutent AVANT les
Macrotasks (setTimeout). Utilisez
queueMicrotask() pour du code
prioritaire. Nettoyez toujours vos setInterval avec clearInterval().