events — EventEmitter
The backbone of Node.js's async model — EventEmitter, on/off/emit/once, error events, and async event patterns.
What it is, in plain English: EventEmitter is the foundation of Node.js's event-driven architecture. Almost everything in Node.js (streams, HTTP servers, file watchers) extends EventEmitter. You call emitter.on(event, listener) to subscribe, emitter.emit(event, ...args) to publish, and emitter.off(event, listener) to unsubscribe. The 'error' event is special — if emitted with no listener, Node.js crashes.
Publishing and subscribing to events
import { EventEmitter } from "events";
const emitter = new EventEmitter();
// Subscribe (.on — fires every time):
emitter.on("data", (payload) => {
console.log("Received:", payload);
});
// Subscribe once (.once — fires only the first time):
emitter.once("connect", () => {
console.log("Connected! (fires once only)");
});
// Publish (emit an event):
emitter.emit("connect"); // "Connected! (fires once only)"
emitter.emit("connect"); // nothing — listener removed after first call
emitter.emit("data", { id: 1 }); // "Received: { id: 1 }"
emitter.emit("data", { id: 2 }); // "Received: { id: 2 }"
// Unsubscribe:
function handler(data) { console.log(data); }
emitter.on("event", handler);
emitter.off("event", handler); // alias: removeListener()Extending EventEmitter
// Most Node.js built-ins extend EventEmitter:
import { EventEmitter } from "events";
class DatabaseConnection extends EventEmitter {
async connect(url) {
try {
// ... connect to db ...
this.emit("connect", { url, status: "connected" });
} catch (e) {
this.emit("error", e); // ALWAYS handle 'error' event
}
}
async query(sql) {
const rows = []; // ... execute query ...
this.emit("query", { sql, rowCount: rows.length });
return rows;
}
close() {
// ... close connection ...
this.emit("close");
}
}
const db = new DatabaseConnection();
db.on("connect", ({ url }) => console.log("Connected to:", url));
db.on("error", (e) => console.error("DB error:", e.message)); // REQUIRED
db.on("close", () => console.log("Disconnected"));The error event is special
// If 'error' is emitted with no listener → Node.js CRASHES:
const emitter = new EventEmitter();
emitter.emit("error", new Error("oops")); // ← UnhandledEmitterError: crash!
// Always add an error listener:
emitter.on("error", (err) => {
console.error("Emitter error:", err.message);
// handle or log — don't let it crash your server
});
Try It Yourself
Official Sources
The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.