Node.js Event Emitter

Node’s event-driven architecture allows us to execute certain actions when something happens. This is done via objects (called “emitters”) which can emit named events that cause functions (“listeners”) to be executed. Objects that emit events are instances of node’s EventEmitter class, made available via the events module. In this article, we’ll look at node’s event emitter.

Creating an Emitter

Let’s create an event to explore some of the basic concepts with node’s EventEmitter

// Require in the events module 
const EventEmitter = require('events');
const carEvent = new EventEmitter();

The events module provides us with the EventEmitter class. We then create an instance of EventEmitter called carEvent. Now let’s explore some of the methods available to us.

Adding a listener

As mentioned earlier listeners are callbacks that get executed when we emit a named event. Here’s how you’d create an event listener on our carEvent emmiter.

carEvent.on('start', function(){
  console.log('Started the car.');
});

Here we are registering a listener for the event named start. This will be executed when we emit an event of said name.

We can also add multiple listeners to a single event. Let’s add another:

carEvent.on('start', function(){
  console.log('Car started. Ready to go!');
});

Next, we’ll emit events to trigger these listeners.

Emitting an Event

All listeners for an event will be called synchronously in the order in which they were registered.

We trigger the listener(s) for an event by calling the emit() method with the name of the event as the first argument. Any subsequent arguments will be passed on as arguments to the listeners.

carEvent.emit('start', 'Hello! ');
// Started the car.
// Car started. Ready to go!

Above we emitted the start event which resulted in all listeners attached to the start event being executed. Now lets update our second listener to make it accept an argument.

carEvent.on('start', function(greeting){
  console.log(greeting, 'Car started. Ready to go!');
});

Now we emit the start event and get the following:

carEvent.emit('start', 'Hello!');
// Started the car.
// Hello! Car started. Ready to go!

Removing a listener from an event

The removeListener() method removes a listener from an event. This takes the name of the event, and the handler function to be removed as arguments. Calls to this method only removes a single instance of a listener, so if you have a listener that was added multiple times then you’d have to call the removeListener() method multiple times to remove each listener.

function a(){
  console.log('Called listener function');
}
// Add listener to event
carEvent.on('A', a);
// Emit event
carEvent.emit('A');
// Called listener function
// Remove listener
carEvent.removeListener('A', a);
// Emit event again
// Nothing happens, event was removed
carEvent.emit('A');

The removeListener method emits an event, removeListenerafter the listener has been removed.

More methods

The on() and emit() methods are the most commons ones used when working with event emitters in node. However, lets take a look at some other useful methods available to us.

Once

The once() method adds a listener that will be executed only, you guessed it :), once.

// Adds a listener to be executed once
carEvent.once('stop', function(message){
  console.log(message);
});

Now when we emit the stop event, node will remove the listener(from the list of listeners attached to the event) then invoke it.

// Executes the first time we emit the stop event
carEvent.emit('stop', 'Stopping....');
// Stopping....
// Emit the stop event a second time
// Nothing happens
carEvent.emit('stop', 'Stopping....');


setMaxListeners

The setMaxListeners() method allows you to set to the maximum number of listeners that can be attached to a single event. The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.

// Sets a maximum of two listeners for any event on the carEvent emitter
carEvent.setMaxListeners(2);

If we add more than two listeners to any event then we’ll get a warning like the following:

// Add thre listeners to a single event
carEvent.on('eventA', function(greeting){});
carEvent.on('eventA', function(greeting){});
carEvent.on('eventA', function(greeting){});
(node:17787) Warning: Possible EventEmitter memory leak detected. 3 eventA listeners added. Use emitter.setMaxListeners() to increase limit

listeners

The listeners() method returns an array of the listeners registered for an event.

const listeners = carEvent.listeners('start');
console.log(listeners);
// [ [Function], [Function] ]

eventNames

Returns an array listing the name of events for which the emitter has registered listeners.

console.log(carEvent.eventNames());
// [ 'start', 'stop', 'eventA' ]

Extending The EventEmitter Class

We can create our own objects that has its own set of properties and methods along with the ones provided by node’s EventEmitter.

const EventEmitter = require('events');
class Car extends EventEmitter{
    constructor(brand, year){
      super();
      this.brand = brand;
      this.year = year;
    }
    turnRadioOn(){
      console.log('radio turned on');
    }
}

Above we created a class that inherits from the EventEmitter class as well as having two properties(brand, and year) of its own along with a method, turnRadioOn.

Now instances of the Car class will have access to both the properties and methods on the Car class as well as all the ones inherited from the EventEmitter class.

const car = new Car('BMW', '2021');
// Adds a listener
car.on('start', function(){ console.log(this.brand + ' started') });
// Emit the event
car.emit('start');
// BMW started
// Call method defined on Car class
car.turnRadioOn();
// radio turned on

Conclusion

Node’s EventEmitter allows us to create objects with listeners that gets executed when we emit an event that the listener is registered to.
We covered methods including the on(), emit(), removeListener() methods. We also looked at how we can extend the EventEmitterwhen creating our own classes.

Did you find this useful? Let me know if the comments. Until next time, think, learn, create, repeat!

About the Author

One thought on “Node.js Event Emitter

  1. Hello! I’m at work surfing around your blog from my new iphone 4! Just wanted to say I love reading through your blog and look forward to all your posts! Keep up the superb work!

Leave a Reply

Your email address will not be published.

You may also like these