Events & EventEmitter
Node's event-driven core — emit named events and register listeners with the EventEmitter pattern.
Node is event-driven: much of its API is built on the idea of emitting named events and listening for them. Servers, streams, and many core objects are EventEmitters under the hood. Understanding the pattern unlocks how Node's building blocks talk to each other.
const EventEmitter = require('node:events');
const bus = new EventEmitter();
// register a listener for the 'order' event
bus.on('order', (item) => {
console.log('New order:', item);
});
// emit the event — every listener runs
bus.emit('order', 'espresso'); // New order: espresso
bus.emit('order', 'latte'); // New order: latteon(event, listener) subscribes; emit(event, ...args) fires it, calling every registered listener synchronously with the arguments you pass. once(event, listener) runs a listener a single time, then removes it.
#Your own emitters
const EventEmitter = require('node:events');
class Timer extends EventEmitter {
start() {
this.emit('tick', Date.now());
}
}
const t = new Timer();
t.on('tick', (at) => console.log('tick at', at));
t.start();The special 'error' event
If an EventEmitter emits an 'error' event and no listener is registered for it, Node throws and can crash the process. Always attach an .on('error', ...) listener to emitters that might emit errors (like streams and servers).
What happens when you call `bus.emit('order', 'latte')` with two 'order' listeners registered?
Key takeaways
- Node is event-driven; many core objects (servers, streams) are EventEmitters.
- `on(event, fn)` subscribes; `emit(event, ...args)` fires all listeners synchronously.
- `once(event, fn)` runs a listener a single time.
- Extend EventEmitter to give your own classes emit/on.
- Always handle the 'error' event — an unhandled one can crash the process.
What does this print?
const EventEmitter = require('node:events');
const e = new EventEmitter();
e.on('ping', n => console.log('pong', n));
e.emit('ping', 1);
e.emit('ping', 2);This emitter crashes the process. What's the safest fix?
const e = new EventEmitter();
e.emit('error', new Error('boom'));Complete the line so the listener runs only the first time 'ready' fires.
emitter.('ready', () => console.log('go'));
Create an EventEmitter chat, register a listener for a 'message' event that logs '💬 ' + text, then emit a 'message' with the text 'hello'.
Try it yourself — a starting point to build on:
# Write your solution here