Sung Qee
Sung Qee

Reputation: 345

Some confusion about nodejs threads

I have some confusions about nodejs thread.

As far as I know, nodejs is running in a single thread. If there is a async function is invoked, nodejs will create a new thread to run these async code. After the async code finished. event loop will get async result and trigger the callback function in another new thread.

In order to test, I conducted the following code test:

var fs = require("fs");

fs.readFile('package.json','utf-8', function (err, data) {
    if(err)
        console.log(err)
    else
        console.log(data);
});

console.log("before loop");
while(true);
console.log("after loop");

my expected result is :

before loop
-- package.json content --

Actually get:

before loop

I may be wrong in some places.

Question:

  1. why while(true) blocked the readFile() or blocked it`s callback function?
  2. what is the relationship between these threads?

Upvotes: 1

Views: 127

Answers (2)

Sung Qee
Sung Qee

Reputation: 345

I found some other awesome answers here :

The calling of this callback function serves as the initial frame in the call stack, and due to JavaScript being single-threaded, further message polling and processing is halted pending the return of all calls on the stack. Subsequent (synchronous) function calls add new call frames to the stack (for example, function init calls function changeColor).

It resolved my confusion again! I am more clear now!

Upvotes: 0

Tadas Paplauskas
Tadas Paplauskas

Reputation: 1903

You are correct in that nodejs is running in a single thread. You can start separate processes and put a load balancer in front of those processes to make use of multicore processors, but that is not implemented in the node itself.

However, node does not spin up a thread for every async function it encounters. It puts those function calls into event loop that runs constantly. The important thing here is that event loop is non-blocking, which means the order of function call excecution is not guaranteed - this is the reason why callbacks are the basis for all node.js programs. That means that for example while one function is waiting for file to be found in the filesystem and read to the buffer, event loop does not stop everything to wait for it to complete and continues to the next call. But in no way is this multi-threaded behaviour. Event loop is not excecuting anything in parallel, it's just constantly switching between tasks. This is just multitasking :)

In your example, a while(true) is blocking the event loop, because it's not an async function call. Do not forget that not everything in javascript is async - only function calls can be async and not other language constructs, such as loops or conditionals. So in your example you run async file reader which is added to the event loop and started. While the file system is doing it's thing, event loop has nothing to do and moves on to console.log("before loop") message. After that you block event loop with while(true) loop. This means event loop cannot put it on hold and go to the filereader anymore.

Hope that clears things up. The main takeaway here is that not everything in javascript is or has to be asynchronous, but most time-consuming operations that are dealing with different devices, such as filesystem or network, are implemented in a non-blocking way. Async function only makes sense when it uses some outside component - you would not use async square root function, as it would block the event loop just the same. This is the reason why node.js is not recommended for heavy computational operations, such as audio/video encoding - async advantage just would not make sense here.

Upvotes: 6

Related Questions