Kurz: JavaScript führt Code in einem Ablauf (Thread) aus und kann trotzdem Timer, Klicks und Netzwerkantworten bedienen. Das Geheimnis ist die Event Loop.
Teil des Kurses JavaScript
Kapitel 27 von 40 im Kurs JavaScript. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.
JavaScript führt Code in einem Ablauf (Thread) aus und kann trotzdem Timer, Klicks und Netzwerkantworten bedienen. Das Geheimnis ist die Event Loop.
Timer
| Funktion | Wirkung |
|---|---|
setTimeout(f, ms) | f einmal nach ms Millisekunden |
setInterval(f, ms) | f wiederholt alle ms Millisekunden |
clearTimeout(id), clearInterval(id) | Timer abbrechen |
requestAnimationFrame(f) | vor dem nächsten Bildaufbau (nur Browser) |
queueMicrotask(f) | sofort nach dem aktuellen Code |
let n = 0;
const id = setInterval(() => {
n++;
console.log("Tick", n);
if (n === 3) {
clearInterval(id);
console.log("gestoppt");
}
}, 20);
const abbruch = setTimeout(() => console.log("wird nie ausgegeben"), 500);
clearTimeout(abbruch);Ausgabe:
Tick 1
Tick 2
Tick 3
gestopptWie die Event Loop arbeitet
- Der Call Stack führt den aktuellen Code aus.
- Langsame Aufgaben (Timer, Netzwerk) übernimmt der Browser/Node im Hintergrund.
- Wenn sie fertig sind, landet ihr Callback in einer Warteschlange.
- Sobald der Call Stack leer ist, holt die Event Loop den nächsten Callback.
Es gibt zwei Warteschlangen mit Vorrang:
| Warteschlange | Beispiele | Wann |
|---|---|---|
| Microtasks | Promise-Callbacks, queueMicrotask | direkt nach dem aktuellen Code, vor allem anderen |
| Macrotasks | Timer, Klicks, I/O | danach, einer pro Runde |
console.log("1 synchron");
setTimeout(() => console.log("5 Timer (Macrotask)"), 0);
Promise.resolve().then(() => console.log("3 Promise (Microtask)"));
queueMicrotask(() => console.log("4 queueMicrotask"));
(async () => {
console.log("2 async-Funktion läuft synchron bis zum ersten await");
await null;
console.log("4b nach await (Microtask)");
})();Ausgabe:
1 synchron
2 async-Funktion läuft synchron bis zum ersten await
3 Promise (Microtask)
4 queueMicrotask
4b nach await (Microtask)
5 Timer (Macrotask)Den Ablauf nicht blockieren
Ein langer Code-Block hält alles an: Die Seite reagiert nicht mehr, Timer verspäten sich.
const start = Date.now();
setTimeout(() => console.log("Timer verspätet:", Date.now() - start >= 200), 0);
while (Date.now() - start < 200) { /* blockiert 200 ms */ }
console.log("Schleife fertig");Ausgabe:
Schleife fertig
Timer verspätet: trueGegenmittel:
- Arbeit in kleine Stücke teilen und zwischendurch
setTimeout(..., 0)oderawaiteinschieben - Schwere Berechnungen in einen Web Worker (Browser) oder Worker Thread (Node.js) auslagern
- Auf Fortschritt asynchron warten statt in einer Schleife abzufragen
Arbeit in Stücke teilen
const pause = () => new Promise(r => setTimeout(r, 0));
async function summiere(bis) {
let summe = 0;
for (let i = 1; i <= bis; i++) {
summe += i;
if (i % 250000 === 0) await pause(); // gibt der Event Loop Luft
}
return summe;
}
summiere(1000000).then(s => console.log("Summe:", s));
setTimeout(() => console.log("Timer kam zwischendurch dran"), 0);Ausgabe:
Timer kam zwischendurch dran
Summe: 500000500000Debounce und Throttle
Bei häufigen Ereignissen (Tippen, Scrollen) willst du nicht jedes Mal reagieren:
function debounce(fn, ms) {
let id;
return (...args) => {
clearTimeout(id);
id = setTimeout(() => fn(...args), ms);
};
}
const suche = debounce(text => console.log("Suche nach:", text), 50);
suche("j"); suche("ja"); suche("jav"); suche("java");Ausgabe:
Suche nach: javaDebounce wartet, bis es ruhig ist, Throttle lässt höchstens eine Ausführung pro Zeitraum zu.
Merke
- JavaScript hat einen Ablauf; langsame Dinge laufen im Hintergrund und melden sich per Callback
- Microtasks (Promises) laufen vor Macrotasks (Timer, Events)
- Lange Schleifen blockieren alles: aufteilen oder in einen Worker verlagern
setTimeout/setIntervalmitclear...abbrechen- Debounce fasst schnelle Ereignisse zusammen
Übungsaufgabe
Baue einen Countdown von 5 bis 0 mit setInterval, der sich selbst beendet und am Schluss “Start!” ausgibt.
Quiz zur Selbstkontrolle
Was läuft zuerst?
- Synchroner Code, dann Microtasks, dann Timer (richtig)
- Timer, dann Promises
- Promises, dann synchroner Code
- Alles gleichzeitig
Was passiert bei einer langen while-Schleife?
- Alles andere (Timer, Klicks) wartet (richtig)
- Sie läuft im Hintergrund
- Der Browser startet einen neuen Thread
- Sie wird automatisch gekürzt
Wie brichst du ein setInterval ab?
- clearInterval(id) (richtig)
- stopInterval(id)
- setInterval(null)
- break
Weiter im Kurs
Zurück: async/await und fetch
Weiter: Das DOM: Elemente finden und ändern
Alle Kapitel: JavaScript im Überblick