Node.js Event Emitter
Tags: node, eventdriven, webdev, javascript
Published: 2021-08-05 08:33:12

<!-- wp:paragraph -->
<p>Node's event-driven architecture allows us to execute certain actions when something happens. This is done via objects (called "emitters") which can <em>emit </em>named events that cause functions ("listeners") to be executed. Objects that emit events are instances of node's EventEmitter class, made available via the <code>events</code> module. In this article we'll look at node's event emitter.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Creating an Emitter</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Let's create an event to explore some of basic concepts with node's EventEmitter</p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p>The <code>events</code> module provides us with the <code>EventEmitter</code> class. We then create an instance of <code>EventEmitter </code>called <code>carEvent</code>. Now let's explore some of the methods available to us.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Adding a listener</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>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 <code>carEvent</code> emmiter.</p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p>Here we are registering a listener for the event named <em>start</em>. This will be executed when we emit an event of said name.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We can also add multiple listeners to a single event. Let's add another:</p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p>Next we'll emit events to trigger these listeners.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Emitting an Event</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>All listeners for an event will be called synchronously in the order in which they were registered.</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We trigger the listener(s) for an event by calling the <code>emit()</code> method with the name of the event as the first argument. Any  subsequent arguments will be passed on as arguments to the listeners. </p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p>Above we emitted the <em>start</em> event  which resulted in all listeners attached to the <em>start</em> event being executed. Now lets update our second listener to make it accept an argument. </p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p>Now we emit the <em>start </em>event and get the following:</p>
<!-- /wp:paragraph -->

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

<!-- wp:heading -->
<h2>Removing a listener from an event</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The <code>removeListener()</code> 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  <code>removeListener()</code> method multiple times to remove each listener.</p>
<!-- /wp:paragraph -->

``` javascript
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');
```

<!-- wp:paragraph -->
<p>The <code>removeListener</code> method emits an event,  <code>removeListener</code>,  after the listener has being removed. </p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>More methods</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The <code>on()</code> and <code>emit() </code>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.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Once</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The <code>once()</code> method adds a listener that will be executed only, you guessed it :) , once.</p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p>Now when emit the <em>stop </em> event, node will remove the listener(from list of listeners attached to the event) then invoke it.</p>
<!-- /wp:paragraph -->

``` javascript
// 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....');
```

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>setMaxListeners</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The <code>setMaxListeners()</code> 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&nbsp;<code>Infinity</code>&nbsp;(or&nbsp;<code>0</code>) to indicate an unlimited number of listeners.</p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p>If we add more than two listeners to any event then we'll get a warning like the following:</p>
<!-- /wp:paragraph -->

``` javascript
// Add thre listeners to a single event
carEvent.on('eventA', function(greeting){});
carEvent.on('eventA', function(greeting){});
carEvent.on('eventA', function(greeting){});
```

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">(node:17787) Warning: Possible EventEmitter memory leak detected. 3 eventA listeners added. Use emitter.setMaxListeners() to increase limit</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>listeners</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The <code>listeners()</code> method returns an array of the listeners registered for an event.</p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>eventNames</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Returns an array listing the name of events for which the emitter has registered listeners.</p>
<!-- /wp:paragraph -->

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

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Extending The EventEmitter Class</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We can create our own objects that has its own set of properties and methods along with the ones provided by node's <code>EventEmitter</code>.</p>
<!-- /wp:paragraph -->

``` javascript
const EventEmitter = require('events');

class Car extends EventEmitter{
  constructor(brand, year){
    super();
    this.brand = brand;
    this.year = year;
  }

  turnRadioOn(){
    console.log('radio turned on');
  }
}
```

<!-- wp:paragraph -->
<p>Above we created a class that inherits from the <code>EventEmitter</code> class as well as having two properties(<em>brand, and year</em>) of its own along with a method,<em> turnRadioOn</em>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now instances of the <code>Car</code> class will have access to both the properties and methods on the <code>Car </code>class as well as all the ones inherited from the  <code>EventEmitter</code> class.</p>
<!-- /wp:paragraph -->

``` javascript
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
```

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->
<h1>Conclusion</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Node's EventEmitter allows us to create objects with listeners that gets executed when we emit an event that the listener is registered to. <br>We covered methods including the <code>on()</code>, <code>emit()</code>,  <code>removeListener()</code> methods. We also looked at how we can extend the <code>EventEmitter</code>when creating our own classes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Did you find this useful? Let me know if the comments. Until next time, <em>think, learn, create, repeat!</em></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->