In this lesson, you will learn how to extend the EventEmitter class to build a custom, decoupled pub-sub (Publisher-Subscriber) messaging architecture.
Beyond Simple Events
Up until now, you have used the EventEmitter to listen for events on objects. In a "Pub-Sub" architecture, we move beyond simple event listening to create a central "Message Bus." This allows different parts of your application to talk to each other without needing direct references to one another.
By extending EventEmitter, you can create specialized classes that manage their own internal event logic, effectively hiding the complexity of your event-driven system behind a clean, public API.
Building a Message Broker
To build this, we create a class that inherits from EventEmitter. This gives our class the ability to register listeners (on) and trigger actions (emit) globally across your application.
const EventEmitter = require('events');
class MessageBroker extends EventEmitter {
publish(topic, data) {
console.log(`[Broker] Broadcasting to ${topic}`);
this.emit(topic, data);
}
subscribe(topic, callback) {
this.on(topic, callback);
}
}
// Usage
const bus = new MessageBroker();
bus.subscribe('user-login', (user) => {
console.log(`System: Welcome back, ${user.name}!`);
});
bus.publish('user-login', { name: 'Alice' });
Why extend the class?
When you extend EventEmitter, you aren't just using a tool; you are defining the contract of your messaging system.
- Encapsulation: By adding specific methods like
publishandsubscribe, you restrict how others interact with your events, preventing accidental use of internal methods likeremoveAllListenersif you don't want them exposed. - Global Coordination: You can create a singleton instance of this broker and share it across your modules. Because it inherits from
EventEmitter, it serves as a central clearinghouse where one module canpublisha notification when a file is processed, and another cansubscribeto that event to update a database or send an email.
This pattern keeps your code decoupled, as the sender of the message doesn't need to know who (or how many) subscribers are listening.
Key Takeaway: Extending EventEmitter allows you to encapsulate your application’s communication logic into a custom message bus, decoupling your modules while providing a standardized interface for event-based coordination.