Blocking and Non-Blocking Node.js operations

in this article, we discuss Blocking and Non-Blocking Node.js operations

Blocking and Non-Blocking Node.js operations

Blocking and Non-Blocking Node.js operations

You know that Node.js is based on an event-driven non-blocking I/O model. You may be wondering what does it mean for something to be blocking or something not to be blocking. In fact, there are both types of operations available in Node.js. However, in order to create performant applications, only one kind should be used.

Accessing external resources

Blocking or non-blocking operating model is relevant when dealing with input/output operations. Writing to a resource or reading from a resource are considered I/O operations. The targets for such operations can be anything from files to network sockets to screen to the keyboard. Any resource that is not accessible instantly at the machine instruction level but involves waiting instead requires I/O communication.

Computer memory, on the other hand, can be addressed instantly and does not require waiting. Accessing memory is therefore not considered an I/O operation. In fact, the random-access memory (RAM) name originates from its ability to access any location in the same amount of time irrespective of its physical location.

Blocking and Non-Blocking Node.js operations

Blocking Operations

A blocking operation occurs when the execution of javascript operations is pulsed and must wait for a non-javascript operation to complete executing. By non-javascript operations, I mean operations like reading or writing data to a file, making a network request, reading or persisting data to a database e.t.c.

Blocking operations occurs in node.js because Javascript in its most basic form is a synchronous, blocking, single-threaded language which can only perform several operations one at a time and since Node.js is a cross-platform JavaScript runtime environment, it runs its operations in a single process without creating a new thread for every request.

Blocking and Non-Blocking Node.js operations

Let’s look at the code snippet below;

 const fs = require('fs');
 
 //reads a file in a synchronous and blocking way
 const readFileSynchronously = (filepath) => {
   console.log('***Reading file***');
   const data = fs.readFileSync(filepath, {encoding: 'utf8'});
   console.log(data);
   console.log('***Data read***');
  return data;
 }
 
 const calculateArraySum = (arr) => {
   return arr.reduce((acc, curr) => acc + curr )
 }
 
 readFileSynchronously('./text.txt');
 
 const sum = calculateArraySum([1, 2, 3, 4, 5, 6, 7]);
 console.log('Sum: ', sum);

The text file contains the following text

This is a text file.

You can write anything here.

Running the above code displays the following on the terminal

***Reading file***
  This is a text file.
  You can write anything here.
  ***Data read***
  Sum:  28

Let’s understand what’s happening here. Line 4 creates a function readFileSynchronously. The fs (file system) method readFileSync on line 6 performs a synchronous file reading and blocks all other operation till it finish reading the file.

Looking at the code output, line 16 calls the readFileSynchronously function which prints line 5 then waits for the data to be read, print it on line 7 then prints line 8. In all these, line 18 waits for the function call to complete before executing, and line 19 prints the sum of the array.

The code looks simple and straight forward but it has the disadvantage of the third line blocking the execution of the additional javascript code. Imagine if we have a super large file that can take several seconds to read, then the execution of the additional javascript code will have to wait for the data to finish reading. Meanwhile, the calculateArraySum function need not bother with the data being read from the file and so there is no point waiting for the data to be read before executing.

Non-blocking operations

Node.js provides a set of asynchronous I/O primitives in its standard library that prevent Javascript code from blocking other additional javascript code. In general, Node.js libraries are written using an asynchronous, non-blocking paradigm.

Let’s rewrite the blocking operation to work asynchronously

 const fs = require('fs');
 
 const readFileAsynchronously = (filepath) => {
   console.log('***Reading file***');
   fs.readFile(filepath, {encoding: 'utf8'}, (err, data) => {
     console.log(data);
     console.log('***Data read***');
   });
 }

 const calculateArraySum = (arr) => {
   return arr.reduce((acc, curr) => acc + curr )
 }
 
 readFileAsynchronously('./text.txt');
 
 const sum = calculateArraySum([1, 2, 3, 4, 5, 6, 7]);
 console.log('Sum: ', sum);

Running the above in node.js environment will give the output below

***Reading file***
  Sum:  28
  This is a text file.
  You can write anything here.
  ***Data read***

Take a look at the output, line 18 executes and prints the sum before the data from the file is displayed on line 6. This happened because the fs method readFile performs an asynchronous operation and does not block the execution of other javascript code but instead, it accepts a function (popularly referred to as a callback function) as its the third argument and calls that function with the data when it’s done reading the text file or calls it with an error if it encounters an error.

In summary, node.js runs in a single thread, but it provides a set of different I/O primitives in its library that runs asynchronously, thereby providing code that runs concurrently.

i hope understand the article Blocking and Non-Blocking Node.js operations

Also Checkout What are the error conventions in Node.js 2021

If you interested in Entertainment genre please check this also Celebrity Birthday Today

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *