Thursday, May 30, 2024

Node.js Event Driven Architecture

In this article we'll talk about the event-driven architecture of Node.js and how it makes Node.js more efficient, scalable and non-blocking.

What is event-driven architecture

Event-driven architecture uses events to trigger processing. You can think of it as one entity which emits an event and another entity that handles that event. An event is a change in state, with JavaScript in browser it can be a keyboard button press event, mouse click event and so on.

Event-driven architecture promotes loose coupling making the system scalable, more responsive and extensible.

Features of event-driven architecture

Some of the features of event-driven architecture are as given below-

  1. Asynchronous- In event-drive architecture events are processed asynchronously. Generally, a system that can store fired events and process them concurrently is used which means event handler is not blocked and remains responsive.
    NodeJS event-driven programming
  2. Loosely-coupled- In event-driven architecture communication between entities is handled using events. One entity emitting the event and another entity handling it keeping both of the entities independent of each other.
  3. Scalable- Because of the loosely coupled architecture event-driven systems are scalable and more efficient.

Event-driven architecture in NodeJS

NodeJS follows the event-driven architecture that is why NodeJS is asynchronous and non-blocking and event loop in NodeJS plays an important role in it.

If we take example of a non-blocking IO operation in NodeJS that's how it works-

  1. With the asynchronous, non-blocking IO operation there will be an associated callback function (event handler).
  2. While an I/O operation (like reading or writing a file) is in progress, NodeJS doesn't wait for I/O operations to complete. It can continue executing other tasks.
  3. Once the I/O operation is finished an event is emitted and the callback function associated with the I/O operation is added to the poll queue to eventually be executed. Event loop, while looping the pending events comes to the poll phase and executes the event handlers (callback functions) stored in the poll queue.

Here is an example of an I/O operation of reading a file using 'fs' module.

const fs = require('fs');
const path = require('path');

fs.readFile(path.join(__dirname, 'Hello.txt'), 'utf8', (err, data) => {
    if(err){
        console.error('Error while reading file', err);
        return;
    }
    console.log(data);
})

console.log('Waiting for file to be read....');

If you run this file the output is-

node app.js

Waiting for file to be read....
Hello from nodeJS

In the above code fs.readFile() is an asynchronous I/O operation.

The callback function is this part-

(err, data) => {
    if(err){
        console.error('Error while reading file', err);
        return;
    }
    console.log(data);
}

You can notice from the output that file read operation doesn't block the system that's why 'Waiting for file to be read....' message is displayed while file reading is still in progress.

When the I/O operation of reading a file completes that emits an event which leads to the execution of the callback function where the content of the file is displayed.

Node.js Event emitter

NodeJS provides functionality to build your own system of emitting and handling events by using the events module.

The events module has a class named EventEmitter which is used to handle our custom events.

You can initialize EventEmitter class as given below-

const EventEmitter = require('events');
const eventEmitter = new EventEmitter();

The eventEmitter object has the on and emit methods.

  • emit is used to trigger an event
  • on is used to add a callback function that's going to be executed when the event is triggered

NodeJS EventEmitter example

const EventEmitter = require('events');

//EventEmitter object
const eventEmitter = new EventEmitter();

// associate callback function with an event
eventEmitter.on('start', () => {
    console.log('Started event handling');
    // trigger another event
    eventEmitter.emit('data_process'); 
});


eventEmitter.on('data_process', () => {
    console.log('Processing started');
});

// trigger 'start' event
eventEmitter.emit('start'); 
  
console.log("Completed");

On running it output is as given below.

Started event handling
Processing started
Completed

That's all for this topic Node.js Event Driven Architecture. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Node.js REPL
  2. NodeJS NPM Package Manager
  3. Creating HTTP server in Node.js
  4. NodeJS Blocking Non-blocking Code
  5. JavaScript Array reduce() Method With Examples

You may also like-

  1. Angular Custom Two-Way Data Binding
  2. Directives in Angular
  3. JSX in React
  4. React HelloWorld App - First React App
  5. Method Overriding in Java
  6. Python continue Statement With Examples
  7. Spring Boot Observability - Distributed Tracing, Metrics
  8. Spring Boot Event Driven Microservice With Kafka

No comments:

Post a Comment