Deutsch (DE) Übersetzung

Node.js - Event Loop: Entschlüsselung der Magie hinter asynchronem JavaScript

Hallo那里,未来的编码巫师们!Heute machen wir uns auf eine aufregende Reise ins Herzen von Node.js - den Event Loop. Keine Sorge, wenn du noch nie eine Zeile Code geschrieben hast; ich werde dein freundlicher Führer durch diese faszinierende Welt sein. Am Ende dieses Tutorials wirst du verstehen, wie Node.js es schafft, so viele Dinge gleichzeitig zu erledigen, genau wie du Hausaufgaben, Netflix und Nachrichten an deine Freunde gleichzeitig erledigen kannst!

Node.js - Event Loop

Was ist der Event Loop?

Stell dir vor, du bist ein Koch in einer beschäftigten Restaurantküche. Du hast mehrere Gerichte gleichzeitig in der Küche, Timer ticken und Bestellungen kommen herein. Wie managst du alles, ohne das Essen zu verbrennen oder die Kunden zu warten? Genau das macht der Event Loop für Node.js!

Der Event Loop ist wie ein Chefkoch, der ständig überprüft, was Aufmerksamkeit erfordert und dafür sorgt, dass alles reibungslos läuft. Es ist das Geheimrezept, das es Node.js ermöglicht, nicht-blockierende I/O-Operationen durchzuführen, obwohl JavaScript einzeln-threaded ist.

Schlüsselkonzepte

Bevor wir tiefer einsteigen, lassen wir uns mit einigen Schlüsselkonzepten vertraut machen:

  1. Einzeln-threaded: JavaScript läuft auf einem einzigen Thread, was bedeutet, dass es gleichzeitig nur eine Sache tun kann.
  2. Nicht-blockierend: Node.js kann mehrere Operationen gleichzeitig ohne Warten auf den Abschluss jeder einzelnen Operation durchführen.
  3. Asynchron: Aufgaben können jetzt gestartet und später beendet werden, während andere Codezeilen im Hintergrund laufen.

Wie funktioniert der Event Loop?

Lassen wir den Event Loop in verdauliche Schritte aufteilen:

  1. Ausführen synchrone Code in der Aufrufstack
  2. Überprüfen auf Timer (setTimeout, setInterval)
  3. Überprüfen auf ausstehende I/O-Operationen
  4. Ausführen von setImmediate-Callbacks
  5. Behandeln von 'close'- Ereignissen

Nun sehen wir das Ganze mit einigen Codebeispielen in Aktion!

Beispiel 1: Synchrone vs. asynchrone Code

console.log("Erster");

setTimeout(() => {
console.log("Zweiter");
}, 0);

console.log("Dritter");

Was denkst du, welche Ausgabe wird es geben? Lassen wir es auseinandernehmen:

  1. "Erster" wird sofort protokolliert.
  2. setTimeout wird erreicht, aber anstatt zu warten, setzt Node.js einen Timer und führt fort.
  3. "Dritter" wird protokolliert.
  4. Der Event Loop überprüft abgeschlossene Timer und führt den Callback aus, der "Zweiter" protokolliert.

Ausgabe:

Erster
Dritter
Zweiter

Überrascht? Dies zeigt, wie Node.js asynchrone Operationen ohne Blockierung des Hauptthreads behandelt.

Beispiel 2: Mehrere Timer

setTimeout(() => console.log("Timer 1"), 0);
setTimeout(() => console.log("Timer 2"), 0);
setTimeout(() => console.log("Timer 3"), 0);

console.log("Hallo vom Hauptthread!");

In diesem Beispiel setzen wir mehrere Timer mit einer Verzögerung von 0 Millisekunden. Der Event Loop wird sie jedoch immer noch nach dem Abschluss des Hauptthreads verarbeiten.

Ausgabe:

Hallo vom Hauptthread!
Timer 1
Timer 2
Timer 3

Die Phasen des Event Loop

Nun, da wir den Event Loop in Aktion gesehen haben, lassen wir uns seine Phasen genauer ansehen:

1. Timer-Phase

Diese Phase führt Callbacks aus, die von setTimeout() und setInterval() geplant wurden.

setTimeout(() => console.log("Ich bin ein Timer!"), 100);
setInterval(() => console.log("Ich wiederhole alle 1 Sekunden"), 1000);

2. Ausstehende Callbacks-Phase

Hier führt der Loop I/O Callbacks aus, die auf die nächste Loop-Iteration verschoben wurden.

3. Leer, Vorbereitungsphase

Nur für internen Gebrauch. Nichts zu sehen hier, Leute!

4. Poll-Phase

Holt neue I/O-Ereignisse ab und führt I/O-bezogene Callbacks aus.

const fs = require('fs');

fs.readFile('example.txt', (err, data) => {
if (err) throw err;
console.log(data);
});

5. Check-Phase

setImmediate()-Callbacks werden hier aufgerufen.

setImmediate(() => console.log("Ich bin sofort!"));

6. Close-Callbacks-Phase

Einige Close-Callbacks, z.B. socket.on('close', ...), werden hier verarbeitet.

Alles zusammenbringen

Lassen wir ein komplexeres Beispiel erstellen, das verschiedene Aspekte des Event Loop nutzt:

const fs = require('fs');

console.log("Start");

setTimeout(() => console.log("Timeout 1"), 0);
setImmediate(() => console.log("Immediate 1"));

fs.readFile('example.txt', (err, data) => {
console.log("Datei Lesen abgeschlossen");
setTimeout(() => console.log("Timeout 2"), 0);
setImmediate(() => console.log("Immediate 2"));
});

console.log("Ende");

Die Ausführungsreihenfolge könnte dich überraschen:

  1. "Start" und "Ende" werden sofort protokolliert.
  2. Der erste setTimeout und setImmediate werden in die Warteschlange eingereiht.
  3. Die Dateilesenoperation beginnt.
  4. Der Event Loop startet seine Zyklen:
  • Der erste setTimeout-Callback wird ausgeführt.
  • Der erste setImmediate-Callback wird ausgeführt.
  • Wenn das Lesen der Datei abgeschlossen ist, wird deren Callback ausgeführt.
  • Innerhalb des Dateilesen-Callbacks werden ein weiterer setTimeout und setImmediate in die Warteschlange eingereiht.
  • Der zweite setImmediate wird vor dem zweiten setTimeout ausgeführt.

Häufige Event Loop-Methoden

Hier ist eine Tabelle häufiger Event Loop-bezogener Methoden in Node.js:

Methode Beschreibung
setTimeout(callback, delay) Führt den Callback nach delay Millisekunden aus
setInterval(callback, interval) Führt den Callback regelmäßig alle interval Millisekunden aus
setImmediate(callback) Führt den Callback in der nächsten Iteration des Event Loop aus
process.nextTick(callback) Fügt den Callback zur "next tick queue" hinzu, die nach dem aktuellen Vorgang verarbeitet wird

Schlussfolgerung

Glückwunsch! Du hast gerade die ersten Schritte in die faszinierende Welt von Node.js und seinem Event Loop gemacht. Denke daran, dass das Erlernen asynchronen Programmierens wie das Fahrradfahren ist - Übung macht den Meister. Lass dich nicht entmutigen, wenn es nicht sofort klappt - weiter experimentieren und bald wirst du wie ein Profi nicht-blockierenden Code schreiben!

Zum Abschluss noch eine lustige Analogie: Stell dir den Event Loop als Karussell vor. Verschiedene Aufgaben (wie Timer, I/O-Operationen und sofortige Callbacks) sind wie Kinder, die darauf springen wollen. Der Event Loop dreht sich ständig, holt und lässt Aufgaben in einer bestimmten Reihenfolge ab, stellt sicher, dass jeder eine Chance bekommt, ohne dass das Karussell jemals anhält.

Weiter codieren, bleib neugierig und denken daran - in der Welt von Node.js ist Geduld nicht nur eine Tugend, sie ist ein Callback!

Credits: Image by storyset