Node.js-Blog#02-Part-A: When in Node a JavaScript function is invoked; where does it place the new frame?

Node.js-Blog#02-Part-A: When in Node a JavaScript function is invoked; where does it place the new frame?

Answer of this question requires a very good understanding of Nodejs Event loop and call stack. This blog however having two parts. In Part-A, I am going to explain the followings:

  • What is Event loop?
  • As we know, there is an issue with this because JavaScript is synchronous. So how does Node.js allow V8 to execute synchronous JavaScript code while performing asynchronous operations?
  • What causes blocking the event loop?

And in Part-B, followings will be discussed details:

  • What is Call Stack?
  • How event loop interact with call stack?
  • How to queue a function execution?

1. What is Event Loop?

  • The Event Loop is one of the most important aspects to understand about Node.js.
  • Why is this so important?

    Because it explains how Node.js can be asynchronous and have non-blocking I/O, and so it explains basically the "killer app" of Node.js, the thing that made it this successful.

  • The Node.js JavaScript code runs on a single thread. There is just one thing happening at a time.

    This is a limitation that's actually very helpful, as it simplifies a lot how you program without worrying about concurrency issues. You just need to pay attention to how you write your code and avoid anything that could block the thread, like synchronous network calls or infinite loops.

  • In general, in most browsers there is an event loop for every browser tab, to make every process isolated and avoid a web page with infinite loops or heavy processing to block your entire browser.

  • The environment manages multiple concurrent event loops, to handle API calls for example. Web Workers run in their own event loop as well.

    You mainly need to be concerned that your code will run on a single event loop, and write code with this thing in mind to avoid blocking it.

1.1 Event Loop in Chrome V8 Engine and how does Node.js allow V8 to execute synchronous JavaScript code while performing asynchronous operations?

  • The Chrome V8 engine is responsible for executing JavaScript code - libuv is a multi-platform support library with a focus on asynchronous I/O. It was primarily developed for use by Node.js.
  • The V8 engine takes in JavaScript as a string, executes it and then prints the result to STDOUT.

    However, there is an issue with this because JavaScript is synchronous. So how does Node.js allow V8 to execute synchronous JavaScript code while performing asynchronous operations? V8 is Google's open source high-performance JavaScript and WebAssembly engine, written in C++.It is used in Chrome and in Node. js, among others.

|       |<-------QUEUE  <--------   |       |
|       |                           |       |
|  V8   |                           |   OS  |
|       |                           |       |
|       |----->/Event Loop\ ------> |       |
|       |      \____Libuv______/    |       |

The diagram can be broken down into these steps:

  • V8 runs JavaScript that requires an asynchronous task to be performed
  • The libuv library submits a request to the OS to perform the task
  • The task is placed onto a queue of tasks that will complete sometime in the future
  • The event loop constantly checks to see if any tasks in the queue are complete
  • Once the event loop finds a completed task it returns it to continue executing the corresponding JavaScript callback.

Code Example-01:

var fs = require('fs');
var path = './data/lorem.txt';

fs.readFile(path, 'utf8', function(err, data) {
  console.log('Async!');
  err ? console.error(err) : console.log(data);
});

console.log('Done!');
  • From this code, it should now be more clear how the program logs "Done!" before it logs the contents of the file.
  • The V8 engine continues to execute the JavaScript outside of the callback and when the asynchronous task is complete the Node.js event loop notifies V8 and runs the callback.

1.2 Blocking the event Loop

  • Any JavaScript code that takes too long to return back control to the event loop will block the execution of any JavaScript code in the page, even block the UI thread, and the user cannot click around, scroll the page, and so on.
  • Almost all the I/O primitives in JavaScript are non-blocking. Network requests, filesystem operations, and so on. Being blocking is the exception, and this is why JavaScript is based so much on callbacks, and more recently on promises and async/await.

    In JavaScript there are 5 primitive types: undefined, null, boolean, string and number.

Whats Next? Part-B jahidularafat.hashnode.dev/nodejs-blog02-pa..