Node.js: Event And Event Emitter - Day Three

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.

event

Let’s start with a simple example.

Example 1

code

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

code

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

code

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

code

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
  1. var events = require('events');  
  2.   
  3. function Sum() {  
  4.     events.EventEmitter.call(this);  
  5.     this.Add = function(a, b) {  
  6.         this.emit('Add', a, b);  
  7.     };  
  8.     this.Sub = function(a, b) {  
  9.         this.emit('Sub', a, b);  
  10.     };  
  11.     this.Mul = function(a, b) {  
  12.         this.emit('Mul', a, b);  
  13.     };  
  14.     this.Div = function(a, b) {  
  15.         this.emit('Div', a, b);  
  16.     };  
  17. }  
  18. Sum.prototype.__proto__ = events.EventEmitter.prototype;  
  19. var Obj = new Sum();  
  20. Obj.on('Add'function(a, b) {  
  21.     console.log('Sum IS=' + (a + b));  
  22. });  
  23. Obj.on('Sub'function(a, b) {  
  24.     console.log('Sub IS=' + (a - b));  
  25. });  
  26. Obj.on('Mul'function(a, b) {  
  27.     console.log('Mul IS=' + (a * b));  
  28. });  
  29. Obj.on('Div'function(a, b) {  
  30.     console.log('Div IS=' + (a / b));  
  31. });  
  32. Obj.Add(10, 20);  
  33. Obj.Sub(40, 20);  
  34. Obj.Mul(20, 50);  
  35. Obj.Div(200, 50);  
Output

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.

code

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.

code

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
  1. // load Event Module  
  2. var event = require('events');  
  3. //Load util Module  
  4. var Util = require('util');  
  5.   
  6. function Demo() {  
  7.     this.String = "This is Demo Constructor";  
  8. };  
  9. Util.inherits(Demo, event);  
  10. Demo.prototype.greet = function(data) {  
  11.     console.log(this.String);  
  12.     this.emit('Callme', data);  
  13. };  
  14. var Obj = new Demo();  
  15. Obj.on('Callme'function(data) {  
  16.     console.log("This is Callme function");  
  17.     console.log("My Name is= " + data);  
  18. });  
  19. Obj.greet('Pankaj');  
Output

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.

code

You can check the “_proto__” property of Demo class. It is similar to a prototype of “eventEmitter” class.

code

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.

code

Using “eventEmitter.once” method, it is possible to register an event listener, which will be invoked only one time.

code

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.

code

ListenerCount

This method returns the numbers of the listeners added for a given event.

code

AddListener(even, listener)

The AddListener method is the method I used to add a listener for an event.

code

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.

code

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
  1. function Emitter() {  
  2.     this.events = {};  
  3. };  
  4. Emitter.prototype.on = function(type, listener) {  
  5.     this.events[type] = this.events[type] || []  
  6.     this.events[type].push(listener);  
  7. };  
  8. Emitter.prototype.emit = function(type) {  
  9.     if (this.events[type]) {  
  10.         this.events[type].forEach(function(listener) {  
  11.             listener();  
  12.         })  
  13.     };  
  14. }  
  15. 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
  1. var Obj = require('./Custom');  
  2. var Emit = new Obj();  
  3. Emit.on('click'function() {  
  4.     console.log("This is click Event1");  
  5. });  
  6. Emit.on('click'function() {  
  7.     console.log("This is click Event2");  
  8. });  
  9. Emit.on('check'function() {  
  10.     console.log("This is check Event1");  
  11. });  
  12. Emit.on('check'function() {  
  13.     console.log("This is check Event2");  
  14. });  
  15. Emit.emit('click');  
  16. 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

Output

Thanks for reading the article. If you have any queries, write them in the comment section.


Similar Articles