Skip to content

Introduction to Node.js

Node.js is an open-source and cross-platform JavaScript runtime environment. Node runs the V8 JavaScript engine outside of the browser - mostly used in the server side programming. It is suitable to write a small demos to real world large server side applications. Node offers its own programming API and it can be expanded with a thousands of 3rd party modules with Node.js’ package ecosystem.

A Node based app is running in a single process without creating a new thread for every request. Node.js provides a set of asynchronous I/O primitives in its standard library that prevent JavaScript code from blocking. For example when Node is performing an I/O operation (like reading from the network, accessing a database or the filesystem) instead of blocking the thread and wasting CPU cycles waiting, Node will resume the operations when the response comes back. This allows Node to handle thousands of concurrent connections with a single server. On the other hand Node is non-blocking, which means it can run many task simultaneously.

You have DOM, document and window objects, when you are coding JavaScript with browser. Remember, those doesn't exist when you are working with Node in the backend. In server side you have (love) all the nice API's what Node is providing through it's modules.

Usually Node is used to create application which is using web protocols like HTTP, TCP, UDP, DNS and SLL or programs which are reading/writing data to the file system or databases.

Link: Official documentation of Node.js, Guides and API.

Traditional Web Application vs Node.js Event loop

Any other Web Application developed without Node.js typically follows Multi-Threaded Request-Response model. In this model, client sends request to the server then server do some work based on the client's request, prepare to response and send response back to the client. Every request will create a new thread to the server side. If there aren't any thread available to use then client request will wait to previous request finishes. In this way, the web server model is synchronous or said to be a blocking.

Image 01

Whenever Node.js runs a program, a thread is automatically created at the same time. This thread is the only starting place where your code is going to be executed. Inside of it, the event loop is generated. If the request from the client side is a non-blocking, it will be served immetiately and the response will be sent back to the client. If the request is a blocking one (for example requiring I/O operations), the request will be sent to the worker thread pool. In this scenario, the request have a callback function that will be fired after the request is finished. Worker thread will send request back to the event loop, which send's it back to the client. This way the blocking request can be handled asynchronously in Node.js.

Image 02

Quote

IO is essentially any action that depends on a resource outside of your application. This means things like databases, external services etc. In addition, NodeJS considers system calls (filesystem access etc.) IO via non-blocking code. Overview of Blocking vs Non-Blocking

Based on the above explanation, we can assume that most server side applications simply deal in IO. They query databases and request external services to provide data to the client application performing the request. This means that most server side applications will spend majority of their execution time waiting on external resources.

Example: use GET request to get all persons from the database

1
2
3
4
5
6
app.get('/persons', async (request, response) => {
  // Make a request to an external database. 
  // While this is happening, server can continue serving other requests.
  const persons = await Person.find({})
  response.json(persons)
})

Thanks to the event loop in Node.js, operations that perform IO can be pushed to the event loop. While we wait for the request to the external resource to finish, we can yield the control of the thread back to the server application, so it may handle new requests.

This is what makes Node.js very powerful:

  • Simple mental model of operating in a single thread.
  • Non-blocking IO.

Read more

Goals of this topic

Understand

  • The concept of Node.js.