1

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?
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Sung Qee
  • 335
  • 4
  • 17
  • The magic of callbacks works because of closures. When you pass a function to `readFile`, it keeps that function alive, and it keeps all the variables captured in the closure alive. Later, node can suddenly call that function (assuming you have returned to node's event loop), and from the programmer perspective, it is extremely convenient, because the closure carries variables across calls. It is okay to return from that code sample you showed, because any necessary variables will stay alive and be reachable from any functions that need them. – doug65536 May 19 '16 at 08:01

2 Answers2

6

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.

Tadas Paplauskas
  • 1,863
  • 11
  • 15
  • Thank you ,Tadas. You mean my code that is not in a async function will run in an synchronous way in the `event-loop` and invoked async function will run in an asynchronous way in `event-loop`? – Sung Qee May 19 '16 at 08:05
  • What i mean is that while(true) is a synchronous operation that cannot be finished or put on hold, so event loop has no way to go back to filereader and the program freezes. There are no separate event loops for sync/async functions, it's all in the same domain. – Tadas Paplauskas May 19 '16 at 08:09
0

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!

Community
  • 1
  • 1
Sung Qee
  • 335
  • 4
  • 17