Getting Started with Node.js Event Emitter

Node.js has an asynchronous event-driven architecture. This allows designs where events emitted due to an action can cause listener object(s) to be executed. Node.js has a built-in module events. This module has an object Event Emitter which we can manipulate to listen to events.

1. Prerequisites

This article assumes you have basic knowledge in JavaScriptREPL, and Node.js installed in your local development environment.

2. Event emitter object

The Event Emitter object lies within the events module. It has an eventEmitter.on() method which it exposes to allow for function(s) to be attached to emitted events.

Let’s begin by importing the events module:

~$ node
Welcome to Node.js v15.12.0.
Type ".help" for more information.
> const events = require('events');
undefined
> const eventEmitter = new events.EventEmitter();
undefined
> 

In the scripts above, we first import the events module. We then create an instance of the Event Emitter class.
Alternatively, we can import the events module and extend the main class with our custom myEventEmitter class as seen below:

$ node
Welcome to Node.js v15.12.0.
Type ".help" for more information.
> const EventEmitter = require('events');
undefined
> class MyEventEmitter extends EventEmitter {}
undefined
> const myEventEmitter = new MyEmitter();
undefined
> myEventEmitter.on('event', () => {
...   console.log('an event emitted!');
... });

> myEventEmitter.emit('event');

It’s important to note that any event emitting object in Node.js is a member of the Event Emitter class.

3. Emitting events

The idea of events in Node.js is quite straightforward. Event emitting object emit named events. These events cause the listeners previously registered to be called.

Let’s look at an event emitting example:

$ node
Welcome to Node.js v15.12.0.
Type ".help" for more information.
> const eventEmitter = require(`events`);
undefined
> class MyEventEmitter extends eventEmitter{}
undefined
> const myEmitter = new MyEventEmitter();
undefined
> function myFirstEvent(){
... console.log(`my first event occurred`);
... }
undefined
> function mySecondEvent(){
... console.log(`hooray, another event has occured`);
... }
undefined
> myEmitter.on('event', myFirstEvent);
MyEventEmitter {
  _events: [Object: null prototype] { event: [Function: c1] },
  _eventsCount: 1,
  _maxListeners: undefined,
  [Symbol(kCapture)]: false
}
> myEmitter.on('event', myFirstEvent);
MyEventEmitter {
  _events: [Object: null prototype] {
    event: [ [Function: myFirstEvent], [Function: myFirstEvent] ]
  },
  _eventsCount: 1,
  _maxListeners: undefined,
  [Symbol(kCapture)]: false
}
> 

When we emit the event event, myFirstEvent() and mySecondEvent() callbacks should be invoked.

Output:

--------------------------
> myEventEmitter.emit(`event`);
my first event occurred
hooray, another event has occurred
true
> 

4. Registering for the event to be fired only one time using once

Previously, we discussed that event listeners were invoked each time an event they are attached to is emitted.
There exist scenarios where we only need to execute these listeners once. In these cases, we make use of the eventEmitter.once().
Let’s take a look at an example:

--------------------
>myEventEmitter.once('MyOnceEvent', () => console.log('my once event fired')); 

Emit MyOnceEvent event:

-----------------------
> myEventEmitter.emit('MyOnceEvent');

Output:

my one event fired

Let’s try to emit this event again:

> myEventEmitter.emit('MyOnceEvent');

The event was emitted once and cannot be emitted again, resulting in a blank screen.

5. Registering for the event with callback parameters

The eventEmitter.emit() method allows the listener functions to be passed arguments. Let’s take a look at how we can achieve this functionality:

myEventEmitter.on('status', (statusCode, statusMsg)=> console.log(`Status code = ${code} while message= ${statusMsg}`));
myEventEmitter {
  _events: [Object: null prototype] { status: [Function (anonymous)] },
  _eventsCount: 1,
  _maxListeners: undefined,
  [Symbol(kCapture)]: false
}
> 

Pass parameters:

----------------
> myEventEmitter.emit('status', 201, 'created');
> 

Output:

Status code =201 while message= created

6. Error events

Error events are emitted whenever an error occurs within an EventEmitter instance. In case an eventEmitter does not have registered error events, an error event will be emitted, exiting the Node.js process.

Let’s look at an example:

---------------------------------------------
> myEmitter.emit('error', new Error('whoops, an error instance!'));
Uncaught [Error: an error instance!] {
  domainEmitter: MyEventEmitter {
    _events: [Object: null prototype] {},
    _eventsCount: 0,
    _maxListeners: undefined,
    [Symbol(kCapture)]: false
  },
  domainThrown: false
}
> false
> 

You will notice that an error is thrown since we don have any listener for the error.

7. Unregistering events

Now that we’ve seen how we can create events, what if we need to unregister them? To unregister the event we created previously, we call the eventEmitter.off() method and pass it to the event as seen below:

myEmitter.off('event', myFirstEvent); // if you try emitting this event, nothing happens

8. Conclustion

In this tutorial, we discussed the EventEmitter object. Using this object, we were able to create an event, fire an event, and listen to it.

We’ve also briefly looked at the error event, that causes the Node.js process to crash.

Happy coding!!

Related posts:

Writing A Multiplayer Text Adventure Engine In Node.js: Creating The Terminal Client (Part 3)
Node.js vs Django
Build and Dockerize a Full-stack React app with Node.js, MySQL and Nginx
Understanding Asynchronous Control Flows in Node.js Using Async.js
Optimizing Critical-Path Performance With Express Server And Handlebars
Getting Started with Fastify Node.js Framework and Faunadb
An Absolute Beginner Guide to Node Package Manager
Most Useful Node.js Packages
Getting Started with HTTP/2 in Node.js
Making a Discord Bot (With Node.js)
Getting Started with Node.js Rate Limiting
API Authentication with Node.js
Generating Authentication Token for Agora Applications
Deploying RESTful APIs using Node.js, Express 4 to Kubernetes clusters
How To Build A CLI Tool With Node.js And PhantomJS
Writing A Multiplayer Text Adventure Engine In Node.js: Adding Chat Into Our Game (Part 4)
Open-sourced node.js modules at Browserling
Useful Node.js Tools, Tutorials And Resources
React To The Future With Isomorphic Apps
Session Management in Node.js using ExpressJS and Express Session
Data Encryption and Decryption in Node.js using Crypto
The Nodemailer package in a Node.js Server
Debugging a Node.Js app using Chrome Dev Tools
Building A Node.js Application Using Docker
How to Send SMS in Node.js using Vonage's SMS API
Building A Room Detector For IoT Devices On Mac OS
Converting A Static Site to A Dynamic Node.js Web App
Building a RESTful Web API in Node.js using PostgresSQL and Express
How To Harness The Machines: Being Productive With Task Runners
Creating Node.js Application Using Express Generator
How to Create a Simple REST API using TypeScript and Node.js
Debugging a Node.js app running in Docker using Nodemon and the Docker extension