Javascript Advanced: What are the Basic I/O Operations in NodeJS

Basic I/O in Node.JS

I/O is a term used frequently in Node.js to describe network or file activities. Network operations allow you to send data from your application to another application or receive data from the outside world. Although we’ll be concentrating on the file system in our examples, you may also investigate these topics utilizing network activities.

The fs core module in Node.js offers file system operations. It has functions that are helpful when working with files and folders. Both synchronous and asynchronous versions of most module functions are available. We can use these features in either a blocking or non-blocking manner.

Synchronous I/O

Working in a Synchronous manner with I/O

We also need a file to read from. Let’s create one named bigdata.txt in the same directory as our source file and add some text to it.

Example:

const fs = require('fs');
console.log('Started!');
const start = Date.now()
 
const text = fs.readFileSync('bigdata.txt', 'utf-8');
 
const end = Date.now()
console.log(`Reading the file for ${end - start} milliseconds`)
console.log('Success!');

Output:

Started!
Reading the file for 0 milliseconds
Success!

Our program outputs the file’s content after reading it. What is this connection to the Event Loop? Node skips the timers step when our application launches because there aren’t any timers. Since there are no I/O callbacks, the phase involving them is skipped. The idle phase is the same. 

The polling stage will then begin. Node executes the console.log() command and requires the fs module during the polling stage. The README.txt file is then read using fs.readFileSync(). Be aware that we omitted to call any callbacks or specify any error handlers. The main thread begins reading the file straight away because this is a synchronous method, and it won’t move on to the next console.log() statement until the read operation is completed.

If you read a larger file, you can observe the delay this results in. Increase the amount of text in “bigdata.txt.” An alternative is to run the following command to download a large-sized example file: run the command below.

$ curl https://raw.githubusercontent.com/Shah-imran/enable-geek-code--snippet/main/bigdata.txt -o bigdata.txt

The file has grown to a couple of MBs. We don’t need to fill up the terminal with text, so you can disable printing the contents of the file on the screen. Rerun the script after that. The brief pause between the first and second console messages caught your attention, right? Given that the application is exerting significant effort to read a file’s content, this suggests that code execution is halted.

Example:

const fs = require('fs');
console.log('Started!');
const start = Date.now()
 
const text = fs.readFileSync('bigdata.txt', 'utf-8');
 
const end = Date.now()
console.log(`Reading the file for ${end - start} milliseconds`)
console.log('Success!');

Output:

Started!
Reading the file for 23 milliseconds
Success!

Asynchronous I/O

Working in an asynchronous manner with I/O

Asynchronous operations in Node.js serve as the language’s equivalent of a “table service” for I/O. Let’s adapt the code from the previous example in order to read the huge file asynchronously.

Example:

const fs = require('fs');
console.log('I am about to read the file');
 
const start = new Date();
fs.readFile('bigdata.txt', (err, data) => {
   if (err) {
       console.log(err);
   } else {
       console.log('Success');
   }
   // console.log(data);
});
const end = new Date();
console.log(`Reading the file for ${end - start} milliseconds`)
console.log('All done!');

Output:

I am about to read the file
Reading the file for 1 milliseconds
All done!
Success

The “All done!” message is printed before the “Success” one, which is the most obvious difference. Let’s examine the event loop, in this case, to discover what is happening.

Like before, when the process first begins, Node skips ahead to the “polling” stage. In that call, Node prints “I am about to read the file” after calling console.log(). The asynchronous read file function fs.readFile() is then called by Node. This time, Node offloads the I/O operation to the asynchronous C++ APIs rather than blocking the thread as it did previously. As the second argument to fs.readFile(), it offers a callback function that will be executed after the read operation is finished.

When it comes to I/O operations, Node.js supports two basic strategies: synchronous, or blocking, and asynchronous, or non-blocking. We explored what happens in the Event Loop to enable a single-threaded application to handle non-blocking asynchronous I/O by looking at sample code using the fs module, which can be either synchronous or asynchronous.

We discovered that the I/O callbacks phase of the Event Loop is where the asynchronous callbacks of I/O operations are handled. By exploiting Node.js’ asynchronous features, our application may carry on with its primary code execution while libUV handles complex file and network activities concurrently.

Share The Tutorial With Your Friends
Twiter
Facebook
LinkedIn
Email
WhatsApp
Skype
Reddit

Check Our Ebook for This Online Course

Advanced topics are covered in this ebook with many practical examples.