Node.js Event Emitter
Node.js - EventEmitter
Section titled “Node.js - EventEmitter”Introduction to Events in Node.js
Section titled “Introduction to Events in Node.js”Node.js operates on an asynchronous, event-driven architecture. This means that many operations in Node.js (like handling network requests, reading files, or interacting with databases) don’t block execution. Instead, they trigger events when they complete or when something significant happens.
The core concept enabling this is the EventEmitter class, found in the built-in events module. Many built-in Node.js objects (like HTTP servers, streams, child processes) inherit from EventEmitter.
The EventEmitter allows objects to emit named events that cause function objects (“listeners”) to be called.
Using the EventEmitter Class
Section titled “Using the EventEmitter Class”You can use EventEmitter directly to implement the observer pattern in your own code. First, import the class:
const EventEmitter = require('events');Then, create an instance:
// Create an eventEmitter objectconst myEmitter = new EventEmitter();Key Methods
Section titled “Key Methods”emitter.on(eventName, listener)oremitter.addListener(eventName, listener): Registers alistenerfunction to be called whenever theeventNameis emitted. Multiple listeners can be added for the same event.emitter.emit(eventName[, ...args]): Emits theeventName. This synchronously calls each registered listener for this event, in order, passing any suppliedargsto them.emitter.once(eventName, listener): Registers alistenerthat will be called at most once for theeventName. The listener is automatically removed after it’s called.emitter.removeListener(eventName, listener)oremitter.off(eventName, listener): Removes the specifiedlistenerfor theeventName.emitter.removeAllListeners([eventName]): Removes all listeners, or just those for the specifiedeventName.emitter.listenerCount(eventName): Returns the number of listeners currently registered for theeventName.
Important Events
Section titled “Important Events”'newListener' (eventName, listener): Emitted before a listener is added.'removeListener' (eventName, listener): Emitted after a listener is removed.'error' (err): A special event. If anEventEmitteremits an'error'event and there are no listeners registered for it, Node.js will typically terminate the process with an uncaught exception. It’s crucial to always register an error listener on EventEmitters that might emit errors.
Example
Section titled “Example”Let’s create a simple example demonstrating the basic usage (eventDemo.js):
const EventEmitter = require('events');
// Create an emitter instanceconst myEmitter = new EventEmitter();
// 1. Register a listener for the 'greet' eventconst listener1 = (name) => { console.log(`Listener 1: Hello, ${name}!`);};myEmitter.on('greet', listener1);
// 2. Register another listener for the 'greet' eventconst listener2 = (name) => { console.log(`Listener 2: Welcome, ${name}!`);};myEmitter.on('greet', listener2);
// 3. Register a one-time listener for 'greet'myEmitter.once('specialGreet', (message) => { console.log(`Special Greeting: ${message}`);});
// Check listener countsconsole.log(`Listeners for 'greet': ${myEmitter.listenerCount('greet')}`); // Output: 2console.log(`Listeners for 'specialGreet': ${myEmitter.listenerCount('specialGreet')}`); // Output: 1
// 4. Emit the 'greet' event with an argumentconsole.log("\nEmitting 'greet' event...");myEmitter.emit('greet', 'Alice');// Both listener1 and listener2 will be called
// 5. Emit the 'specialGreet' eventconsole.log("\nEmitting 'specialGreet' event...");myEmitter.emit('specialGreet', 'This happens only once!');// The listener will be called
console.log(`Listeners for 'specialGreet' after emit: ${myEmitter.listenerCount('specialGreet')}`); // Output: 0
// 6. Remove listener1console.log("\nRemoving listener 1...");myEmitter.removeListener('greet', listener1);console.log(`Listeners for 'greet' after removal: ${myEmitter.listenerCount('greet')}`); // Output: 1
// 7. Emit 'greet' againconsole.log("\nEmitting 'greet' event again...");myEmitter.emit('greet', 'Bob');// Only listener2 will be called now
// 8. Handling ErrorsmyEmitter.on('error', (err) => { console.error('--- An Error Occurred ---'); console.error(err.message);});
console.log("\nEmitting an 'error' event...");myEmitter.emit('error', new Error('Something went wrong!'));// If the error listener wasn't registered, the program would crash here.
console.log('\nProgram Ended.');Run the script:
$ node eventDemo.jsExpected Output:
Listeners for 'greet': 2Listeners for 'specialGreet': 1
Emitting 'greet' event...Listener 1: Hello, Alice!Listener 2: Welcome, Alice!
Emitting 'specialGreet' event...Special Greeting: This happens only once!Listeners for 'specialGreet' after emit: 0
Removing listener 1...Listeners for 'greet' after removal: 1
Emitting 'greet' event again...Listener 2: Welcome, Bob!
Emitting an 'error' event...--- An Error Occurred ---Something went wrong!
Program Ended.This example shows how to register listeners (on, once), emit events (emit), check listener counts (listenerCount), remove listeners (removeListener), and handle the special 'error' event.
Understanding EventEmitter is crucial for working effectively with Node.js core modules and many third-party libraries that rely on asynchronous, event-driven patterns.