🔄Wie JavaScript läuft: die Event Loop

JavaScript hat einen einzigen Call Stack. Asynchrones (Timer, Netzwerk, Events) übernimmt die Umgebung und stellt die Callbacks in Warteschlangen. Wähle ein Programm und gehe Schritt für Schritt durch: Codezeile, Stack, Queues und Konsole werden live angezeigt.

🐞Schritt-Debugger

Schritt 1 / 15 · Tasten ← →
1console.log("1: Skript");
2setTimeout(() => console.log("4: Timeout"), 0);
3Promise.resolve().then(() => console.log("3: then"));
4console.log("2: Skript-Ende");
Synchroner Code (Skript)t = 0 msZeile 1

Das Skript wird als erster Task gestartet: der globale Ausführungskontext liegt auf dem Call Stack.

Call Stack
Skript (global)
Web-APIs / Timer
keine laufenden Timer
Microtask-Queue
leer
Task-Queue (Macrotasks)
leer
Konsole
(noch leer)
Was man daraus lernt: Nach dem Skript wird zuerst die Microtask-Queue komplett geleert, erst dann holt die Event Loop den Timer-Task.
Echte Ausgabe (in den Tests mit Node geprüft): 1: Skript · 2: Skript-Ende · 3: then · 4: Timeout

🧭Die Regeln

📚 Call Stack & Heap

Der Call Stack enthält die gerade laufenden Funktionen (Frames). Objekte liegen im Heap. Solange etwas auf dem Stack liegt, läuft nichts anderes – JavaScript ist „run to completion“.

⚡ Microtasks

Promise-Reaktionen (then/catch/finally), Fortsetzungen nach await und queueMicrotask. Werden nach jedem Task vollständig abgearbeitet – auch neu hinzukommende. Endlos neue Microtasks blockieren deshalb die Seite.

⏰ Tasks (Macrotasks)

Abgelaufene Timer (setTimeout, setInterval), Ereignisse (Klick, Netzwerk), MessageChannel. Pro Runde genau ein Task, danach wieder alle Microtasks, dann ggf. Rendern.

while (true) {
  task = taskQueue.nächster()      // z. B. Skript, Timer, Klick
  führeAus(task)                   // läuft bis der Stack leer ist
  while (microtaskQueue.nichtLeer())
    führeAus(microtaskQueue.nächster())
  if (Browser && Zeit für Frame)
    requestAnimationFrame-Callbacks, Style, Layout, Paint
}
⚠️ setTimeout(fn, 0) heißt „frühestens“
Die Zeit ist eine Mindestwartezeit. In Node.js wird 0 als 1 ms behandelt, Browser setzen bei mehr als fünf ineinander verschachtelten Timern mindestens 4 ms an.
💡 Browser und Node.js
Die Reihenfolge Microtasks vor Tasks gilt in beiden. Node.js hat zusätzlich Phasen (Timer, I/O, setImmediate, close) und process.nextTick, das sogar vor Promise-Microtasks läuft.