Node JS Events
Written By: Avinash Malhotra
Updated on
Events
Any occurrence in node js is an event and the callback function is listener ( Function objects). Node js handle most of its core API in asynchronous event-driven architecture.
There are two type of events in Node JS, build-in events and custom events. build-in events are done on OS level and custom events on NodeJS.
Build-in events
The build-in events are handled by libuv, a C library to handle all I/O asynchronously in event loop. The build-in events are happened on OS level.
Build-in Event Example
file open
const fs=require('fs');
fs.ReadStream("./src/data.txt").on("open",()=>{
console.log("file open");
});
Custom Events
The custom events are handled by EventEmitter Class. Node JS has a build-in module to handle custom events. To load the module, use require('events')
.
const event=require('events');
Event Emitter
The events module has a build in class
EventEmitter. The instance of EventEmitter emits events and listners react to events.
Event Emitter class is used to emit events and subscribe to raise events. See an example of how to subscribe an event and then raise it.
Event Emitter Class
const event=require('events').EventEmitter;
let emitter=new event();
// register listener or subscribe
emitter.on('done',(res)=>{
console.log(`event done with ${res} argument`);
});
// Raise, emit or trigger event
emitter.emit('done','hi');
let emitter
is the new instance of EventEmitter class
. To subscribe to event, use on function
with event name a string and callback (listener). To raise event, use event.emit function with event name and argument to listener.
Multiple Subscribers for events
One of the main advantage of using events is having build-in support for multiple subscribers. We can listen multiple events at one time. See example
Event Emitter Class
subscriber 1
subscriber 2
const event=require('events').EventEmitter;
let emitter=new event();
// subscribe
emitter.on('done',()=>{
console.log(`subscriber 1`);
});
// subscribe again
emitter.on('done',()=>{
console.log(`subscriber 2`);
});
//Emit
emitter.emit('done');
All the listeners are called in order they are registered for event.
Argument in events
An argument passed in event is shared between all subscribers. See example.
subscriber 1 city is delhi
subscriber 2 city is delhi
const event=require('events').EventEmitter;
let emitter=new event();
// subscribe
emitter.on('done',(x)=>{
console.log('subscriber 1 city is ', x);
});
// subscribe
emitter.on('done',(x)=>{
console.log('subscriber 2 city is', x);
});
//Emit
emitter.emit('done','delhi');
Check event is done
done
already done
const event=require('events').EventEmitter;
let emitter=new event();
emitter.on("done",(x)=>{
console.log(`done`);
x.handled=true;
})
emitter.on("done",(x)=>{
if(x.handled){
console.log(`already done`);
}
});
emitter.emit('done',{handled:false});
Emit Event once
Once an event is subscribed, we can raise it any number of times. But to raise an event only once, EventEmitter provides a method once. once method raise or emit the listener only once. The next time emit method will not works. See example
event done 1
const event=require('events').EventEmitter;
let emitter=new event();
emitter.once("done",()=>{
console.log("event done 1");
});
emitter.emit('done'); // will emit
emitter.emit('done'); // will not emit
Unsubscribe Event
To unsubscribe from an event, use removeListener function. This will ignore second emit as event is already unsubscribed. See example below.
handled
const event=require('events').EventEmitter;
let emitter=new event();
function eventHandler(){
console.log(`handled`);
// unsubscribe
emitter.removeListener("done",eventHandler);
}
emitter.on('done',eventHandler);
emitter.emit('done'); // will emit
emitter.emit('done'); // will not emit
Error Event
To handle exceptions in node js, error event is used. Without error event, the default action is to print stack trace and then exit.
const event=require('events').EventEmitter;
let emitter=new event();
emitter.emit('error',new Error("Custom Error Message"));
Practical Example of Node JS Events
Lets assume a real scenario where a user will login and create account. First he will login and then his account will be created. To do this, we will use two modules (login.js) and (account.js) is our app src directory. See example
/*server.js*/
const event=require('events').EventEmitter;
let emitter=new event();
module.exports=emitter;
var login=require('./login');
var account=require('./account');
emitter.emit('login',9);
emitter.emit('account');
/*login.js*/
var t=require('./server');
t.on("login",(res)=>{
console.log("Login process starts at",res)
});
t.on("login",(res)=>{
console.log("login process done");
})
/*account.js*/
var t=require('./server');
t.once("account",(res)=>{
console.log("account process done");
});
Output
Login process starts at 9
login process done
account process done