Einleitung: Warum Ihre Website "hängt" und wer schuld ist
\n\nStellen Sie sich ein Restaurant vor, in dem ein einziger Kellner gleichzeitig Bestellungen aufnimmt, Essen serviert, Geschirr spült und die Einnahmen zählt. Chaos, oder? So ähnlich funktioniert der single-threaded JavaScript, wenn Aufgaben nicht richtig verwaltet werden. Wenn wir Code schreiben, der alles auf einmal erledigt – Daten lädt, Klicks verarbeitet, Animationen zeichnet – friert der Browser ein und der Benutzer sieht eine "nachdenkliche" Oberfläche.
\n\nHeute werden wir verstehen, wie Aufgabenwarteschlangen in JavaScript helfen, dieses Chaos in ein geordnetes System zu verwandeln. Sie erfahren, wie der Event Loop Prioritäten verteilt, wie sich Mikrotasks von Makrotasks unterscheiden und wie Hintergrundaufgaben in JavaScript es ermöglichen, den Hauptthread nicht zu blockieren. Am Ende erwarten Sie praktische Beispiele, die Sie sofort in Ihr Projekt integrieren können.
\n\nWie der Event Loop funktioniert: Der Dirigent des Aufgabenorchesters
\n\nIm Zentrum der gesamten Asynchronität steht der Event Loop JavaScript. Dies ist ein Mechanismus, der sich endlos dreht und fragt: "Gibt es etwas auszuführen? Mikrotasks? Rendering?". Wenn Sie sich jemals gefragt haben, warum setTimeout nicht sofort ausgeführt wird, Promise.then jedoch fast augenblicklich – die Antwort liegt genau hier.
Call Stack
\nDies ist der Ort, an den Funktionen zur sofortigen Ausführung gelangen. Solange der Stack belegt ist, passiert nichts anderes. Wenn Ihre Funktion eine Million Zahlen berechnet – friert der Browser ein, weil der Stack nicht freigegeben wird.
\n\nMacrotask Queue
\nHier landen setTimeout, setInterval, DOM-Ereignisse (Klicks, Scrollen), Ressourcenladungen. Der Event Loop nimmt eine Aufgabe nach der anderen aus dieser Warteschlange, führt sie aus, überprüft dann die Mikrotasks, rendert die Seite – und nimmt dann die nächste Makrotask.
Microtask Queue
\nUnd das ist das Königreich von Promise, queueMicrotask, MutationObserver. Mikrotasks haben die höchste Priorität. Sobald der Stack leer ist, führt der Event Loop ALLE Mikrotasks aus, bevor er zur nächsten Makrotask übergeht. Deshalb wird Promise.resolve().then() schneller ausgeführt als setTimeout.
console.log('1');\n\nsetTimeout(() => {\n console.log('2');\n}, 0);\n\nPromise.resolve().then(() => {\n console.log('3');\n});\n\nconsole.log('4');\n\n// Ausgabe: 1, 4, 3, 2\n\n\nDieses Beispiel ist ein Klassiker. setTimeout (Makrotask) wird verschoben, selbst mit einer Verzögerung von null, während Promise.then (Mikrotask) sofort nach dem synchronen Code ausgeführt wird. Das Verständnis dieser Reihenfolge ist der Schlüssel zum Schreiben von vorhersagbarem asynchronem Code.
Hintergrundaufgaben: Wie Sie die Oberfläche nicht blockieren
\n\nUnd nun das Hauptproblem: Was tun, wenn schwere Arbeit erledigt werden muss (Bildverarbeitung, komplexe Berechnungen, Datenparsing)? Wenn Sie dies im Hauptthread ausführen – bleibt die Oberfläche stehen. Die Lösung sind Hintergrundaufgaben in JavaScript.
\n\nWeb Workers – echte Multithreading-Fähigkeit
\nWeb Workers JS ermöglichen es, Code in einem separaten Thread auszuführen. Er hat keinen Zugriff auf das DOM, kann aber Nachrichten mit dem Hauptthread austauschen. Dies ist das ideale Werkzeug für die Warteschlangenverarbeitung in JS im Hintergrund.
\n\n// main.js\nconst worker = new Worker('worker.js');\n\nworker.postMessage({ data: [1, 2, 3, 4, 5, 6] });\n\nworker.onmessage = (event) => {\n console.log('Ergebnis vom Worker:', event.data);\n};\n\n// worker.js\nself.onmessage = (event) => {\n const numbers = event.data.data;\n // Schwere Arbeit: Filtern von geraden Zahlen\n const result = numbers.filter(n => n % 2 === 0);\n self.postMessage(result);\n};\n\n\nBeachten Sie: Der Hauptthread wird nicht blockiert. Der Benutzer kann klicken, scrollen, Text eingeben – alles läuft flüssig, während der Worker rechnet.
\n\n