Node.js Event Emitter

Taslan Graham - Aug 5 '21 - - Dev Community

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 basic concepts with node's EventEmitter

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

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 gets 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.');
});
Enter fullscreen mode Exit fullscreen mode

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!');
});
Enter fullscreen mode Exit fullscreen mode

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!
Enter fullscreen mode Exit fullscreen mode

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!');
});
Enter fullscreen mode Exit fullscreen mode

Now we emit the start event and get the following:

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

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');
Enter fullscreen mode Exit fullscreen mode

The removeListener method emits an event, removeListener, after the listener has being removed.

More methods

The on() and emit() methods are the most commons ones used when 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);
});
Enter fullscreen mode Exit fullscreen mode

Now when emit the stop event, node will remove the listener(from 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....');
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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){});
Enter fullscreen mode Exit fullscreen mode
(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] ]
Enter fullscreen mode Exit fullscreen mode

eventNames

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

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

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');
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!

. . . . . . . . . . . . . . . . .
Terabox Video Player