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.
ReadStream Event
file open
const fs=require('fs');
fs.ReadStream("./src/data.txt").on("open",()=>{
console.log("file open");
});
import fs from '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;
import EventEmitter from "node:events";
let emitter=new EventEmitter();
// 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
import EventEmitter from "node:events";
let emitter=new EventEmitter();
// 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
import EventEmitter from "node:events";
let emitter=new EventEmitter();
// 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
import EventEmitter from "node:events";
let emitter=new EventEmitter();
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
import EventEmitter from "node:events";
let emitter=new EventEmitter();
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
import EventEmitter from "node:events";
let emitter=new EventEmitter();
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.
import EventEmitter from "node:events";
let emitter=new EventEmitter();
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*/
import EventEmitter from "node:events";
let emitter=new EventEmitter();
module.exports=emitter;
import login from './login';
import account from './account';
emitter.emit('login',9);
emitter.emit('account');
/*login.js*/
import t from './server';
t.on("login",(res)=>{
console.log("Login process starts at",res)
});
t.on("login",(res)=>{
console.log("login process done");
})
/*account.js*/
import t from './server';
t.once("account",(res)=>{
console.log("account process done");
});
Output
Login process starts at 9
login process done
account process done