Heard about Node.js' EventEmitter class? Maybe you know that most of the built-in Node libraries use it? Maybe you were always curious about EventEmitter, but had no one to explain it to you?

In this tutorial, I will give you a guided demo of the great EventEmitter class.

You must be familiar with various Node library events like "on data", "on end", "on error", etc. The event mechanism work so flawlessly and perfectly, doesn't it. All courtesy of EventEmitter. All the event-based Node.js libraries are EventEmitters! In OOP lingo, you might say those Node libraries extend EventEmitter.

The power of EventEmitter need not be limited to the built-in Node libraries anymore - now it can be yours too!

The best way to show what EventEmitter is capable is through an example. Take a look at this example:

var EventEmitter = require('events').EventEmitter;
var radium = new EventEmitter();

radium.on('radiation', function(ray) {
    console.log(ray);
});

setInterval(function() {
    radium.emit('radiation', 'GAMMA');
}, 1000);

Notice how easy it is to create custom events, add event listeners, emit events, and pass messages via events. All of those are possible because of the EventEmitter magic. EventEmitter is what makes it possible to write amazing libraries for Node.js.

The above example was based on an instance of EventEmitter; how do we create classes that extend EventEmitter? Node.js has a library named util, which has a method named inherits, which makes it possible to easily extend any class using any other class:

var util = require('util');
util.inherits(MyClass, SuperClass);

Using our new-found knowledge of util.inherits(), we will create a Node.js module that extends EventEmitter. Pay good attention to the comments in the code.

radio.js
var util = require('util');
var EventEmitter = require('events').EventEmitter;

// @station - an object with `freq` and `name` properties
var Radio = function(station) {

    // we need to store the reference of `this` to `self`, so that we can use the current context in the setTimeout (or any callback) functions
    // using `this` in the setTimeout functions will refer to those funtions, not the Radio class
    var self = this;

    // emit 'open' event instantly
    setTimeout(function() {
        self.emit('open', station);
    }, 0);

    // emit 'close' event after 5 secs
    setTimeout(function() {
        self.emit('close', station);
    }, 5000);

    // EventEmitters inherit a single event listener, see it in action
    this.on('newListener', function(listener) {
        console.log('Event Listener: ' + listener);
    });
};

// extend the EventEmitter class using our Radio class
util.inherits(Radio, EventEmitter);

// we specify that this module is a refrence to the Radio class
module.exports = Radio;

There we have created our Node module extending EventEmitter. Now let's see how we can use it in an example script.

example.js
var Radio = require('./radio.js');

// a station object
var station = {
    freq: '80.16',
    name: 'Rock N Roll Radio',
};
// create an instance of the Radio class
var radio = new Radio(station);

// add an 'open' event listener
radio.on('open', function(station) {
    console.log('"%s" FM %s OPENED', station.name, station.freq);
    console.log('♬ ♫♬');
});

// add a 'close' event listener
radio.on('close', function(station) {
    console.log('"%s" FM %s CLOSED', station.name, station.freq);
});

Run test.js and get ready to behold the magic of EventEmitter.

If, for some reason you don't feel like using the util module and doing util.inherits(), you can extend a class (let's say Apple) this way:

Apple.prototype = Object.create(require('events').EventEmitter.prototype);

EventEmitter will help you write impressive event-based Node modules. Also your knowledge of EventEmitter will greatly affect your efficiency as a Node.js developer, so make sure to read more about it and learn how it works inside out. If you don't know EventEmitter, you don't know Node.js yet!

References#

Tweet this | Share on LinkedIn |