Abschnitt 7 · Lektion 1
EventEmitter
Das nächste Muster kennst du schon, du hast es nur woanders gesehen. Im Browser hast du
addEventListener benutzt: Irgendwo passiert etwas, und dein Code reagiert darauf, ohne dass die
auslösende Stelle wissen muss, wer zuhört.
In Node heißt das EventEmitter, und der Unterschied ist nur, dass es nicht an einem DOM-Knoten
hängt, sondern an einem beliebigen Objekt. Die halbe Standardbibliothek baut darauf auf: Server,
Sockets, Streams, Kindprozesse. Wer das Muster kennt, liest fremden Node-Code plötzlich flüssig.
Vier Methoden, mehr braucht es nicht
on meldet einen Zuhörer an. emit löst ein Ereignis aus. once meldet einen Zuhörer an, der nach
dem ersten Mal wieder verschwindet. off meldet einen Zuhörer wieder ab.
import { EventEmitter } from "node:events";
const kueche = new EventEmitter();
kueche.on("bestellung", (tisch, gericht) => {
console.log(`Tisch ${tisch} bekommt ${gericht}`);
});
kueche.emit("bestellung", 4, "Suppe");
kueche.emit("bestellung", 7, "Salat"); Der Ereignisname ist eine Zeichenkette, die du frei wählst. Alles, was du hinter dem Namen an emit
übergibst, kommt bei den Zuhörern als Argumente an, in derselben Reihenfolge. Es gibt kein festes
Format und keine Anmeldung von Ereignisnamen. Ein Tippfehler im Namen ist deshalb kein Fehler,
sondern einfach ein Ereignis, auf das niemand hört.
once, wenn es nur beim ersten Mal zählt
import { EventEmitter } from "node:events";
const melder = new EventEmitter();
melder.on("tick", (nummer) => console.log(`on: ${nummer}`));
melder.once("tick", (nummer) => console.log(`once: ${nummer}`));
melder.emit("tick", 1);
melder.emit("tick", 2);
melder.emit("tick", 3); once ist kein Sonderfall von on, sondern der normale Weg für alles, was einmalig ist:
„Verbindung steht”, „Datei ist fertig gelesen”, „Server hört jetzt zu”. Der Zuhörer entfernt sich
selbst, und du musst nicht daran denken, ihn wieder abzumelden.
Das ist mehr als Bequemlichkeit. Zuhörer, die niemand abmeldet, sind eine der klassischen Ursachen für ein Programm, dessen Speicherverbrauch langsam steigt. Node warnt dich sogar, wenn an einem Ereignis mehr als zehn Zuhörer hängen, und genau darum geht es bei dieser Warnung.
Der Punkt, der die meisten überrascht
import { EventEmitter } from "node:events";
const melder = new EventEmitter();
melder.on("fertig", () => console.log("der Zuhoerer laeuft"));
console.log("vor emit");
melder.emit("fertig");
console.log("nach emit"); emit ruft die Zuhörer synchron auf. Direkt, nacheinander, mitten in der Zeile, in der emit
steht. Nichts daran ist „später” oder „im Hintergrund”.
Das hat zwei Folgen, die man kennen sollte. Erstens: Wenn ein Zuhörer lange rechnet, hält er die
Stelle auf, die emit aufgerufen hat. Ein Ereignis ist kein Weg, Arbeit loszuwerden. Zweitens: Ein
Zuhörer, der du erst nach dem emit anmeldest, verpasst es. Ereignisse werden nicht aufgehoben.
Deshalb hängt man die Zuhörer immer an, bevor man das Objekt losschickt.
Wenn ein Zuhörer eine async-Funktion ist, wartet emit übrigens nicht auf sie. Es ruft sie auf,
bekommt ein Promise zurück und wirft es weg. Wer auf ein Ergebnis warten will, ist bei Ereignissen
falsch, und darum geht es gleich in Lektion 7.2.
Wozu das gut ist
Der eigentliche Gewinn steckt in dem, was nicht im Code steht. Die Küche im ersten Beispiel weiß nicht, wer ihre Bestellungen entgegennimmt. Sie meldet nur, dass eine da ist.
Damit kannst du später einen zweiten Zuhörer dazuhängen, der die Bestellung mitschreibt, und danach einen dritten, der eine Statistik führt. An der Küche ändert sich dabei nichts. Genau dafür ist das Muster gedacht: eine Stelle meldet, dass etwas passiert ist, ohne wissen zu müssen, wen das interessiert.
Zum Mitnehmen
on zum Zuhören, emit zum Auslösen, once für genau ein Mal. Und emit ruft die Zuhörer synchron auf, nicht später.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.
Was in dieser Lektion steckt
-
Artikel mit 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.