Node.js is built around the asynchronous event driven mechanism, so it works very fast and flawlessly. Much of the Node.js core API is built around an idiomatic asynchronous event-driven architecture in which certain kinds of objects (called "emitters") periodically emit named events, which enable the Function objects ("listeners") to be called. All the event-based Node.js libraries are EventEmitters.
All objects, which emit the events are the instances of the EventEmitter class. These objects expose an eventEmitter.on() function, which allows one or more functions to be attached to the named events, emitted by the object. Whenever the EventEmitter object emits an event all the functions attached to the specific event are called synchronously.
You can read more about “event” in built Node.js API, here.
Let’s start with a simple example.
Example 1
In this example, first we load the “events” module, using the require method. In the next line, we generate an instance of EventEmitter class. Further, we create a Fun function and bind this function on the “Hello” event, using the “on” method of EventEmitter class. It means, when “Hello” event will fire, “Fun” function will call. In the last line, we Emit the “Hello” event and in the form of output, “Fun” function is called and “Hello! C#-Corner” message is printed.
Example 2
This example is similar to the previous example, but in this example, we bind three functions for a single event, so all these functions will call synchronously.
Example 3
In this example, we create a set interval of 1000ms. After each 1000ms, “hello” event will fire and all the functions attached to this event will execute.
Passing Arguments to Listeners
In this example, we create a CsharpCorner method, which takes two arguments and binds this function to “info” event of eventEmitter. Thus, when we emit info event, we need to pass the two arguments; i.e., name and city.
Inherit EventEmitter Class
This is the common practice in Node.js to inherit the prototype of EventEmitter class. Let’s take an example and then understand this concept.
Example
- var events = require('events');
-
- function Sum() {
- events.EventEmitter.call(this);
- this.Add = function(a, b) {
- this.emit('Add', a, b);
- };
- this.Sub = function(a, b) {
- this.emit('Sub', a, b);
- };
- this.Mul = function(a, b) {
- this.emit('Mul', a, b);
- };
- this.Div = function(a, b) {
- this.emit('Div', a, b);
- };
- }
- Sum.prototype.__proto__ = events.EventEmitter.prototype;
- var Obj = new Sum();
- Obj.on('Add', function(a, b) {
- console.log('Sum IS=' + (a + b));
- });
- Obj.on('Sub', function(a, b) {
- console.log('Sub IS=' + (a - b));
- });
- Obj.on('Mul', function(a, b) {
- console.log('Mul IS=' + (a * b));
- });
- Obj.on('Div', function(a, b) {
- console.log('Div IS=' + (a / b));
- });
- Obj.Add(10, 20);
- Obj.Sub(40, 20);
- Obj.Mul(20, 50);
- Obj.Div(200, 50);
Output
In this example, we create a function constructor(Sum) and in this function constructor, we implement the “call” method of “EventEmitter” class. This method is used to call a method of an object, substituting another object for the current object.
You can check the definition of the call method in “lib.es6.d.ts” file.
In next lines, we add 4 methods (Add,Mul,Sub and Div) and these methods will be used to emit the event.
“Sum.prototype.__proto__ = events.EventEmitter.prototype”
In this line of code, we implement the prototype inheritance, which means prototype of Class Sum and EventEmitter is the same. Let’s compare the prototype of both the classes.
You can see that the prototype of both “Sum” and “EventEmitter” class is the same, so all the properties and methods of EventEmitter class are also available for the class “Sum”. In the next lines, we added “Add”,”Sub”,”Div” and “Mul” eventlistener for “Obj” objects and in the last 4 lines, we emit the events.
Example
-
- var event = require('events');
-
- var Util = require('util');
-
- function Demo() {
- this.String = "This is Demo Constructor";
- };
- Util.inherits(Demo, event);
- Demo.prototype.greet = function(data) {
- console.log(this.String);
- this.emit('Callme', data);
- };
- var Obj = new Demo();
- Obj.on('Callme', function(data) {
- console.log("This is Callme function");
- console.log("My Name is= " + data);
- });
- Obj.greet('Pankaj');
Output
This example is similar to a previous example. In this example, we use the “inherits” method of “util” module. This method is used to inherit the prototype of the super constructor class to the constructor . You can read more about inherit method in the document of “util” module.
You can check the “_proto__” property of Demo class. It is similar to a prototype of “eventEmitter” class.
Invoke Events Once
When a listener is registered, using the eventEmitter.on() method, the listener will be invoked, every time, the named event is emitted.
Using “eventEmitter.once” method, it is possible to register an event listener, which will be invoked only one time.
In this example, we invoked “info” event two times, but the event listener executed only once.
Maximum Listener
By default, 10 eventListener can be added for an event, but you can change this number, using the setMaxListeners(n) method and getMaxListeners() method can be used to get the numbers of the maximum listeners for an event.
ListenerCount
This method returns the numbers of the listeners added for a given event.
AddListener(even, listener)
The AddListener method is the method I used to add a listener for an event.
RemoveListener(event, listener) and removeAllListeners();
removeListener method is used to remove a listener, attached with an event and removeAllListener is used to remove all the listeners attached with a event.
When we execute this program, we get the error because we remove the “demo” listener and afterwards, we are trying to emit an event.
Create Custom Event Emitter
Now, we will learn, how to create a custom event emitter, register our events, and emit these events.
Custom.js
- function Emitter() {
- this.events = {};
- };
- Emitter.prototype.on = function(type, listener) {
- this.events[type] = this.events[type] || []
- this.events[type].push(listener);
- };
- Emitter.prototype.emit = function(type) {
- if (this.events[type]) {
- this.events[type].forEach(function(listener) {
- listener();
- })
- };
- }
- module.exports = Emitter;
in Custom.js file, we create a function constructor(Emitter) and bind the prototype for “on” and “emit” method. For “on” method, we are registering our events and their listeners. In “emit” method, we invoke the listener.
App.js
- var Obj = require('./Custom');
- var Emit = new Obj();
- Emit.on('click', function() {
- console.log("This is click Event1");
- });
- Emit.on('click', function() {
- console.log("This is click Event2");
- });
- Emit.on('check', function() {
- console.log("This is check Event1");
- });
- Emit.on('check', function() {
- console.log("This is check Event2");
- });
- Emit.emit('click');
- Emit.emit('check');
In this file, we implement the “custom” module, register the “click” and “check” event with their corresponding listener and “emit” all the events.
Output
Thanks for reading the article. If you have any queries, write them in the comment section.