Handle Asynchronous Events in Node.js
10 min read·Jan 1, 2026
In Node.js, the core API is built around an asynchronous event-driven architecture in which certain objects called "emitters" send named signals called "events" to other objects called "listeners" that perform specific actions in response.
The EventEmitter class
All objects that emit events are instances of the EventEmitter class defined in the node:events module:
const EventEmitter = require('node:events');
When the EventEmitter object emits an event, all the functions attached to that specific event are called synchronously.
Create an event emitter
To create an event emitter object, you can use the new keyword to instantiate the EventEmitter class:
const EventEmitter = require('node:events');
const emitter = new EventEmitter();
Emit named events
To emit a named event, you can use the emit() method of the event emitter instance:
emitter.emit(name, ...arguments?);
Where:
nameis the name of the event....argumentsis a list of optional arguments used to send data alongside the named event.
Example
Let's consider this script:
const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.emit('data', 'Hello, World!');
When executed, the emitter instance will emit a "data" event containing the "Hello, World!".
Handle named events
To intercept and handle a named event, you can use the on() method of the event emitter instance:
emitter.on(event, listener);
Where:
eventis the name of the emitted event.listeneris a callback function executed whenever the specifiedeventis emitted, that takes are arguments the arguments specified in the.emit()method.
Note: Since different event emitter instances can emit the same event, only the listener attached to the instance that emitted the event will be triggered.
Example
Let's consider this script:
const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.on('data', (data) => {
console.log(data);
});
emitter.emit('data', 'Hello, World!');
When executed, the emitter instance will intercept the "data" event and log the string passed alongside the event.
Which will produce this output:
Hello, World!
Handle events only once
By default, the listeners registered using the on() method are invoked every time the named event is emitted.
To invoke a listener only once, you can use the once() method instead:
emitter.once(event, listener);
Example
Let's consider this script:
const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.once('start', () => {
console.log('Setting up...');
});
emitter.on('data', (data) => {
console.log('Processing data...', data);
});
emitter.once('end', () => {
console.log('Cleaning up...');
});
emitter.emit('start');
emitter.emit('start');
emitter.emit('data', 'Hello');
emitter.emit('data', 'World');
emitter.emit('end');
emitter.emit('end');
When executed, the emitter instance will emit each of the "start", "data", and "end" events twice, while using the once() method to intercept the "start" and "end" events only once, and the on() method to intercept all "data" events.
Which will produce this output:
Setting up...
Processing data... Hello
Processing data... World
Cleaning up...
Handle errors
When an error occurs within an EventEmitter instance, the typical action is for an error event to be emitted.
As a best practice, there should always be at least one listener attached to the error event in order to prevent the Node.js process from crashing.
Otherwise, whenever an error event is emitted, the error is thrown, a stack trace is printed, and the Node.js process exits.
Example
Let's consider this script:
const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.on('error', (error) => {
console.error(error.message);
});
emitter.emit('error', new Error('Whoops!'));
When executed, the emitter instance will intercept and log the Error object of the "error" event, preventing the application from crashing.
Which will produce this output:
Whoops!
Summary
Here's a summary of what you've learned in this lesson:
- The
EventEmitterclass is used to instantiate new event emitter objects. - The
emit()method is used to emit events with optional data. - The
on()method is used to intercept a specified event as many times as it is emitted. - The
once()method is used to intercept a specified event only once. - The
"error"event is used to intercept errors and prevent the application from crashing.
Enjoying the courses?
I've made these courses completely free so anyone can learn from them. If they've helped you and you'd like to actively support the work behind BackendBrewery, you can leave a tip:
Support BackendBrewery