What is Node.js?
Many people think that Node.js is a framework, while other new students, who are beginners, understand it as a library. But wait, my friends, Node is neither a framework nor a library.
Node.js is a cross-platform, open-source server environment that can run on Windows, Linux, macOS, and other operating systems. Node.js is a back-end JavaScript runtime environment that utilizes the V8 JavaScript engine to execute JavaScript code outside of a web browser. Node is built using programming languages like C, C++, and JavaScript.
You can explore more about Node.js from their official documentation or Wikipedia.
The V8 Engine — the backbone of Node applications
V8 is a free and open-source JavaScript and WebAssembly engine developed by the Chromium Project for Chromium and Google Chrome web browsers. The project’s creator is Lars Bak. V8 Engine is built using JavaScript, C++, ECMAScript, and Assembly languages.
V8 is the name of the JavaScript engine that powers Google Chrome. It’s the thing that takes our JavaScript and executes it while browsing with Chrome. V8 provides the runtime environment in which JavaScript executes. V8 is written in C++, and it’s continuously improved. It is portable and runs on Mac, Windows, Linux, and several other systems.
You can explore more about the V8 Engine from official documentation or Wikipedia.
Performance Myth — Internal Working of Node.js
Many people are still not able to understand the internal workings of Node.js because its non-blocking and asynchronous execution of programs makes it very complex to understand. Especially the internal working of Node.js, which is the Event Loop.
Now, many people have questioned what asynchronous programming is. So, let’s understand what Synchronous and Asynchronous Programming are.
What is Synchronous and Asynchronous Programming?
Synchronous programming means that the code runs in the sequence it is defined. When a function is called and has returned some value in a synchronous program, only then will the next line be executed.
In simple words, synchronous programming means the execution of a program happens line by line. If one line is taking so much time to execute, then the execution of the program will not go to the next line. It waits for that line to execute, and then it will go to the next line. And if one line takes so much time to execute, then the UI will be frozen.
Asynchronous programming, on the other hand, refers to code that doesn’t execute in sequence. These functions are performed not according to the sequence they are defined inside a program, but only when certain conditions are met.
In simple words, Asynchronous means the environment doesn’t wait for a specific line to execute. It will start executing that line and put it into the background, and when the output of that line comes, it will print it to the console. This way the UI will not be frozen, only that part will be frozen whose going to fetch the data from the actual application server.
- JavaScript code
console.log("Hello world!")
setTimeout(()=>{
console.log('set timeout function')
}, 2000)
console.log('I am Parmesh Bhatt.')
- Output
Hello world!
I am Parmesh Bhatt.
set timeout function
Now, let’s understand about Event Loop in Node.js.
Event Loop
An event loop is an endless loop that waits for tasks, executes them, and then sleeps until it receives more tasks. Node handles requests using an Event loop inside the NodeJS environment.
Node.js has mainly three parts in the backend: Call Stack, Call Back Queue, and Node APIs. The combination of all three is called an Event Loop.
Let’s have an example and understand it simply:
Suppose we have a code like below,
let a = 2;
let b = 3;
const sum = a + b;
console.log(sum);
- For this, the output will be,
5
When we write a simple code like the above, the first execution will start, and the main function goes into the Call stack.
**Now you all have a question in JavaScript, we are not writing any main function as we write in C++ and Java. So, where does this main function come in the Call stack?
My friends, JavaScript is internally built. When it starts executing, it will automatically put all of the code in the main function and then start its actual execution.**
After the main function goes into the Call stack, the console.log function goes into the Call stack, and the Call stack executes it, and the output is printed on the screen.
Call Stack has an internal building that follows the LIFO property. LIFO means Last In, First Out. This means whichever function comes last will execute first, and that’s why the main function comes first and gets out of the stack last.
Another example:
console.log('one');
setTimeout(()=>{
console.log("Settimeout 1")
}, 2000)
setTimeout(()=>{
console.log("Settimeout 2")
}, 0)
console.log('Two');
- The output of the above code is:
one
Two
Settimeout 2
Settimeout 1
It’s really interesting. Let’s understand it…
We all know now that in NodeJS, there are three things: the Call stack, the second is Node APIs, and the third is the call-back queue.
When we start executing the above code, as usual, the main function goes into the Call stack, and the console.log function will also go into the Call stack.
But from the setTimeout function, the setTimeout function will not go into the Call stack directly, but it goes into the Node API.
Now you all have a question: Why does it go into the node API directly? Why does it not go into the Call stack?
Let’s understand it,
The setTimeout function goes into the Node API directly because the set timeout function is inherited from C++, and every function that inherits from C++ will always go into the Node API directly, and it will not be executed until it goes into the call stack.
There are many more functions like setTimeout in C++. You may explore it on the Internet.
So the setTimeout 1st function goes into the Node API first, and the thesetTimeoutt 2 function goes into the Node API 2nd.
Then the last console.log will go into the call stack, and the call stack will execute it and print the output. Now the output is one and two. After the execution of the last console, every function present in the Call stack will come out of the Call stack, including the main, and the Call stack is now empty.
When the call stack is empty, the functions that are present in the Node API will go into the Callback Queue one by one.
The functions that have a lower priority will go first into the callback queue. When multiple functions are present in the node API, every function will go one by one into the Callback Queue, and then into the Call Stack.
Every function that is present in the Callback Queue will only go into the Call stack when the Call stack is empty. If the Call stack is not empty, the functions will not go into the call stack from the Callback Queue.
After going into the Call stack, the Call stack executes the functions one by one and prints the output on the console. And that’s why the output is like,
one
Two
Settimeout 2
Settimeout 1
This is how the node works internally, and the combination of the call stack, Node API, and the Callback Queue is known as an Event Loop.
Features of Event Loop
- An event loop is an endless loop that waits for tasks, executes them, and then sleeps until it receives more tasks.
- The event loop executes tasks from the event queue only when the call stack is empty, i.e., there is no ongoing task.
- The event loop allows us to use callbacks and promises.
- The event loop executes the tasks starting from the oldest first.
Conclusion
The event loop allows Node.js to perform non-blocking I/O operations even though JavaScript is single-threaded.
Since most modern kernels are multi-threaded, they can handle multiple operations executing in the background. When one of these operations completes, the kernel tells Node.js so that the appropriate callback may be added to the poll queue to eventually be executed.
Now you should understand why the two-second time delay function does not block the rest of the program from executing…
So, I end my conversation here, but if anybody wants to connect with me, then the links are below…
Top comments (1)
wow this breaks it down so well, makes async stuff less scary. you think the real skill is patience, or just needing to see it in action a lot?