46
Event Emitters in Node.js
On the frontend-side of an application the user interactions are handled through events, click events, keyboard events, mouse moving events, etc. In Node.js (backend-side) we can build a similar system using the events module.
Much of the Node.js core API is built around event-driven architecture. There objects or emitters emit events that cause a function object or listener to be called. For example, HTTP and TCP servers are an event emitter, a TCP socket is an event emitter, HTTP request and response objects are event emitters.
All objects that emit events are instances of the
EventEmitter
class and expose an eventEmitter.on()
function so functions can be attached to the named events. Event names are typically camel-cased.The
events
module exports an EventEmitter
constructor, depending on the Node version the events
module is the EventEmitter
or you have to deconstruct it.const EventEmitter = require('events');
The
EventEmitter
is a constructor
and to create a new event emitter the constructor has to be called with the new
keyword.const myEmitter = new EventEmitter();
A common usage pattern with
EventEmitter
is inheritance. Look at this article for a refresher on Inheritance in Javascript.class MyEmitter extends EventEmitter {
constructor(opts = {}) {
super(opts);
this.name = opts.name;
}
}
The created EventEmitter object exposes two methods -
on
and emit
.emit
is used to trigger an event.on
is used to add a callback function.To emit an event the
emit
method has to be called:const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.emit('event');
The first argument of
emit
is the event namespace. We need to know the event namespace to be able to listen to emitted events.The
eventEmitter.emit()
method allows an arbitrary set of arguments to be passed to the listener functions, like myEmitter.emit('event', 'a', 'b');
The following example emits an error event and a close event when the method destroy is called with an error.
const EventEmitter = require('events')
class MyEmitter extends EventEmitter {
constructor (opts = {}) {
super(opts);
this.name = opts.name;
},
destroy (err) {
if (err) { this.emit('error', err) }
this.emit('close');
}
}
To listen to an emitted event the event emitter object has a method
addListener
or the alias on
.Copy the following code in the Node REPL and execute.
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
eventEmitter.on('close', () => {
console.log('close event fired!');
});
eventEmitter.emit('close');
The output will be
close event fired!
.Arguments passed to
emit
are received by the listener.For example:
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
eventEmitter.on('add', (a, b) => {
console.log('add event fired!');
console.log(a + b);
});
eventEmitter.emit('add', 1, 2);
Ordering is important. Event listeners will not react to events if the event is emitted before the listener is added. Event listeners are also called in the order they are registered.
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
eventEmitter.on('my-event', () => {
console.log('1st');
});
eventEmitter.on('my-event', () => {
console.log('2nd');
});
eventEmitter.emit('my-event');
The output from the code above will be
1st
and then 2nd
.There is a method which can be used to inject listeners to the top
prependListener
.const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
eventEmitter.on('my-event', () => {
console.log('1st');
});
eventEmitter.prependListener('my-event', () => {
console.log('2nd');
});
eventEmitter.emit('my-event');
Now the output will be
2nd
and then 1st
.An event can also be emitted more than once. To reduce this the
once
method can be used. It removes its listener after it has been called.const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
eventEmitter.once('event', () => {
console.log('event fired');
});
eventEmitter.emit('event');
eventEmitter.emit('event');
The output
event fired
will only be logged once.Listeners can be removed with the
removeListener
method. It takes two arguments the event name, and the listener function.const callback = stream => {
console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
removeListener()
will remove, at most, one instance of a listener from the listener array. If a single listener has been added multiple times for the specified eventName, then removeListener()
must be called multiple times to remove each instance.The
removeAllListeners
method can be used to remove listeners without having a reference to their function. It takes one optional argument, the event name. It is useful if multiple listener for the same event name have been registered.Emitting an
error
event on an event emitter will cause the event emitter to throw an exception if a listener for the error
event has not been registered.eventEmitter
is a constructor method.emit
method has to be used with an event name as an argument.on
or addEventListener
can be used with the event name.Thanks for reading and if you have any questions , use the comment function or send me a message @mariokandut.
If you want to know more about Node, have a look at these Node Tutorials.
References (and Big thanks):
46