Node.js Explained for Beginners

Bahadır Mezgil
7 min readOct 21, 2019

--

What is Node.js

Node.js is a server-side Javascript runtime environment that you can build anything you want as REST or GraphQL APIs, WebSocket services, server-rendered web applications, streaming applications, etc. It has a massive community and it has the world’s biggest package manager which is called npm (https://www.npmjs.com).

If you ever googled Node.js, you would probably see terms like event-driven, non-blocking I/O, event loop, event queue, V8 JavaScript engine, etc. Please don’t be afraid of any of these terms. Just follow me through this article step by step.

In this article, you will learn what is Node.js, what is the advantage of it and how it works behind all those fancy terms.

History of Node.js

First, let me begin with Javascript which was created by Brendan Eich in 1995. At that time he was working for Netscape which is the company created the most popular web browser of the 90s called Netscape. He wrote the history in terms of changing the static web pages into functional, behavioral, interactive web applications. At that time, he did not have much time to work extensively on this programming language. We can say that he did a little bit of sloppy work because he developed the prototype of this scripting language in only 10 days. That is why before the ES6 standardization, Javascript was a language that sucks.

Just before the Netscape Company acquisition, its browser source code was released and later it gave birth to Firefox. Through these years, the Javascript programming language gained lots of popularity and accepted as a universal web browser language.

Especially when Google got into the browser race with Google Chrome in 2008, they created V8 JavaScript engine which is a performance-oriented JavaScript interpreter. They used this engine on their browser in order to gain speed for browsing experience.

Thank god it is an open-source project. Thus one year later, the creator of Node.js, Ryan Dahl realizes V8 JavaScript Engine’s potential and worked on using it on the server-side. I want to remind you that it was not the first time JavaScript is used on the server-side but thanks to V8 using Javascript on server-side became efficient and high-performant. Its result was impressive because not only it was high-performant but also like Google Chrome, he built Node.js for working asynchronously in nature. We can also call it non-blocking by default. Let me explain this a little bit in detail.

Asynchronous Node.js

When you write a code line by line, normally you expect that these lines of codes are going to work in exact order. But the I/O operations like a service call, a file read, running a SQL query on the database, these kinds of operations need much more time than normal computations to return a result. If you code your project in a way that these different kinds of operations in order, every I/O operation has to wait for its predecessor.

You can say that it is expected behavior if these operation results are required for the next operation in a chained way.

An example case might be that your user logins to your system with an email and password. So:

  1. You need to find this user record in your database from your user table via his/her email.
  2. You need to check the correctness of the given password (I hope you did it in a hashed way).
  3. If the given password is correct, update the last logged in date field of the related record.

As you can see, finding your user with email, checking the password, updating the last logged in field operations need to be processed in a sequential way.

But let me give you the same example with a different functionality as again your user tries to login with an email and password:

  1. You find this user record in your database from your user table via his/her email.
  2. You check the correctness of the given password.
  3. If the given password is correct, update the last logged in date field of the related record.
  4. Send an email to your user in order to warn him/her about this current login.

So do you think sending the email operation should wait for the updating last logged in date field in your user table and vice versa? Of course not! Sending warning email and updating user information operations don’t have to be processed in a sequential way. If you implement it in a sequential way your service response time will be increased and your web or mobile application will become slow.

These types of examples can be reproduced easily because real-time scenarios have lots of independent operations that don’t have to wait for each other. The solution to that is Node.js non-blocking/asynchronous behavior. In Node.js, you can implement and easily run these operations independently thanks to its nature. By nature means that it Node.js doesn’t understand automatically which lines of code need to be executed in a sequential way or which of them need to be executed asynchronously. You have tools for that as:

  1. Callbacks (The default feature before ES6)
  2. Promises (ES6 feature)
  3. Async/Await functions (ES8 feature)

These 3 items are serving the same thing but while JavaScript standard specifications are improving, we can have more performant, easy to use, also readable code by using the latest ECMAScript version.

Single-Threaded Environment

Node.js is accomplishing this asynchronous behavior in a single-threaded environment. That means you can process one command at a time. But why! Isn’t multithreaded a good thing? Isn’t it can give us much more computational power?

Node.js is developed intentionally as single-threaded because dealing with multi-threading is not easy. It is difficult to develop, maintain and test. Also, it can have serious side-effects which may make your application unreliable. Threads might have race conditions for the same resources and when it comes to the scalability of your application, threads can be really problematic. That is why Node.js is accomplishing this nonblocking structure while having a single-threaded architecture.

But how Node.js is achieving the asynchronous environment with a single thread?

Event Queue and Event Loop

The answer is in the process life cycle elements of Node.js which you may already hear before as the event loop and event queue.

In Node.js, when a line of code needs to be executed first it is inserted into the call stack which is already available in most of the programming languages. The main purpose of the call stack is keeping track of code execution in order.

You can see how the call stack works in synchronous order according to the example code below.

function bar() {  console.log('bar');}function foo() {  console.log('foo');  bar();}foo();

As you can see from the graph, each line of code is inserting to the call stack and they are executing via last in last out order.

But when it comes to the operations needs to be executed asynchronously, same as sync operations, async operation is added to the call stack but this time the event loop step in and it removes it from the call stack. The event loop takes over the non-blocking operations from the call stack and executes them while waiting for the returning results. No matter how many asynchronous operations are there, the event loop takes them from the stack in the same way. When any of these async operations returned with a result, the event loop adds it to the event queue.

When the call stack becomes empty by executing the synchronous operations first because blocking operations always have the priority, then event queue elements are added to call stack via first in first out order which means the fastest resulted one is inserted first.

Lastly, these async operations in the call stack are executed and our call stack becomes empty again.

Thanks to this implementation, the non-blocking operations do not have to wait for each other in a single-threaded environment. Instead of waiting, Node.js thread deals with the other computations.

You can see how the event loop handles async operations and fills the event queue with their results from the below graph:

That is why node.js environment is called event-driven. Because it is working on a single thread and it is not suitable for computation-intensive applications but it is a great work environment for dealing with multiple events.

Don’t worry about multi-core processors because you can get every bit of computational power from them by running separate Node.js instances on each CPU core.

I hope that you understand what is Node.js and it’s work logic behind all unknown words. I will also write new articles about how to install and how to run Node.js in your development environment. Hopefully, I will show you how to build simple applications with Node.js like a Restful API.

Please do not hesitate to contact me about any topic on your mind. See you in new articles.

--

--

Bahadır Mezgil

Hello, I am Bahadır, a passionate full-stack web developer.