Node.js - Event Loop

Introduction

Before reading this article, I highly recommend reading my previous articles.
In this article, we will learn about event loop in Node.js. We will also understand the Node.js code execution process. In my first article, I have told you that Node.js is single threaded application. Because Node.js works on JavaScript and JavaScript doesn't support multi-threading, so Node.js also doesn't support multi-threading. But, Node.js applications can support concurrency, using the concept of event and callbacks. This all can be done using a magical thing of Node.js - "event loop". Let's see how event loop works.
 
Working of Event Loop

In "Getting Started With Node.js" article, I have explained the architecture of Node.js where I discussed that Node.js is divided into two main components, Googles V8 Engine and Libuv. So, event loop is the part of Libuv that is written in C and C++.



The above diagram shows the execution process of Node.js. Let's understand it step by step.
 
Step 1

Whenever a request comes to Node.js API, that incoming request is added to the event queue. This is because Node.js can't handle multiple requests simultaneously. The first time, the incoming request is added to the event queue.
 
Step 2

Now, you can see in the diagram that one loop is there which always checks if any event or request is available in event queue or not. If any requests are there, then according to the "First Come, First Served" property of queue, the requests will be served.
 
Step 3

This Node.js event loop is single threaded and performs non blocking i/o tasks, so it sends requests to C++ internal thread pool where lots of threads can be run. This C++ internal thread pool is the part of event loop developed in Libuv. This can handle multiple requests. Now, event loop checks again and again if any event is there in the Event Queue. If there is any, then it serves to the thread pool if the blocking process is there. 
 
Step 4

Now, the internal thread pool handles a lot of requests, like database request, file request, and many more.
 
Step 5

Whenever any thread completes that task, the callback function calls and sends the response back to the event loop.
 
Step 6

Now, event loop sends back the response to the client whose request is completed.  
 
Example

The following example will show you how event loop works.
  1. var fs = require('fs');  
  2. var i = 1;  
  3. fs.watch("file.txt"function (event, filename) {  
  4.     var EventId = "#" + i;  
  5.     var EventName = " Event: " + event;  
  6.     var FileName = " FileName: " + filename;  
  7.     var Time = " Time: " + new Date();  
  8.     var data = EventId.concat(EventName, FileName, Time, "\n");  
  9.     console.log(data);  
  10.     i++;  
  11. });  
  12. console.log("Now we are watching file.txt\n");  
In the above example, in first line, I am loading a module "fs" which is used for file system and I have taken a variable as "i" counter flag. Now, I am using fs.watch function which is keeping an eye on file.txt file. This watch function has a callback function that contains event and filename. So, whenever an event occurs in this file.txt, this will show you that event in console, because I am logging complete data using console.log function. I have saved the above code with the name app.js.
 
Note - My "file.txt" file is available in the same directory where app.js file exists. My file structure is like the following.

 
 
Now, I am running this program and making changes in file.txt. When saved, we get the following output.



The above program can explain that whenever any event occurs in file.txt file, then the event loop's watch event will be fired and event loop will check if any event occurred in the file or not. You can also log that event in one file. You can use the following code to do the same. 
  1. var fs = require('fs');  
  2. fs.writeFile('log.txt'''function (err) {  
  3.     if (err) throw err;  
  4.     console.log('File Saved Successfully!');  
  5. });  
  6. var i = 0;  
  7. fs.watch("target.txt"function (event, filename) {  
  8.     var EventId = "#" + i;  
  9.     var EventName = " Event: " + event;  
  10.     var FileName = " FileName: " + filename;  
  11.     var Time = " Time: " + new Date();  
  12.     var data = EventId.concat(EventName, FileName, Time,"\n");  
  13.     fs.appendFile('log.txt', data, function (err) {  
  14.         if (err) {  
  15.             console.log(err);  
  16.         }  
  17.     });  
  18.     i++;  
  19. });  
That's it. I hope this article was helpful. Thanks.