Rectangle 27 0

node.js Why does a while loop block the node event loop?


@codecowboy In Node.js there is only one main thread. So all the code has to be executed by that thread only. The setTimeout will schedule the function to be executed after 1 second. So it will not execute the function immediately and move to the next executable statement. It finds a while loop. Since it is single threaded, only when the current task is completed, Node.js can pick the next item from the queue. But then the while runs infinitely and so the function registered by setTimeout never gets a chance to execute.

Node is a single serial task. There is no parallelism, and its concurrency is IO bound. Think of it like this: Everything is running on a single thread, when you make an IO call that is blocking/synchronous your process halts until the data is returned; however say we have a single thread that instead of waiting on IO(reading disk, grabbing a url, etc) your task continues on to the next task, and after that task is complete it checks that IO. This is basically what node does, its an "event-loop" its polling IO for completion(or progress) on a loop. So when a task does not complete(your loop) the event loop does not progress. To put it simply.

Note
Rectangle 27 0

node.js Why does a while loop block the node event loop?


var done = false;

 // set a timer for 1 second from now to set done to true
 setTimeout(function() {
      done = true;
 }, 1000);

 // spin wait for the done value to change
 while (!done) { /* do nothing */}

 console.log("finally, the done value changed!");
done
false
setTimeout()
  • 1 second into the while loop spinning, the timer fires internally to the JS engine and the timer callback is added to the event queue. This likely occurs on a different thread, internal to the JS engine.
  • Get something from the event queue
  • Run whatever task is indicated and run it until it returns
  • The while loop keeps spinning because the done variable never changes. Because it continues to spin, the JS engine never finishes this thread of execution and never gets to pull the next item from the event queue.
  • When the above task is done, get the next item from the event queue

@marshalcraft - ANY loop in Javascript blocks. Javascript is single threaded and event driven so as long as a loop is running, nothing else except the code in the loop can run. And, it's not just loops. Any long running function keeps other things from running. Single threaded - Javascript can only do one synchronous thing at a time. All loops are synchronous. In case you missed it, the summary is in my third paragraph after it explains how the event queue works (which is the key to understanding all this). I don't think that's a very long run around the bush.

Here's a simple example that might help explain it:

Here's what happens internally inside the JS engine:

I apologize jftiend. I was over critical. So non asynchronous functions block. But really a while loop in a asynchronous function would still block. Seems a while loop from start to exit is a single unit of asynchronous execution. I understand js is single threaded. But it doesn't necessarily execute code inline, so it pauses in some cases to continue asynchronous code, or events. Being as it doesn't use time to dictate how much to execute, it must use "atomic" or basic units of execution. Like run global scope code for a little, pause to handle event or do some work on asynchronous function.

If at some point, there is nothing in the event queue, then go to sleep until something is placed in the event queue.

It is conceivable that the js interpreter or runtime could do this on one thread. Also forgive my probably poor js verbage and terminology. I'm not strong with js.

It's fairly simple really. Internally, node.js consists of this type of loop:

So I get a very long run around the bush that while loops block in js.

So, if a piece of Javascript is sitting in a while() loop, then that task is not finishing and per the above sequence, nothing new will be picked out of the event queue until that prior task is completely done. So, a very long or forever running while() loop just gums up the works. Because Javascript only runs one task at a time (single threaded for JS execution), if that one task is spinning in a while loop, then nothing else can ever execute.

Some might logically think that the while loop will spin until the timer fires and then the timer will change the value of done to true and then the while loop will finish and the console.log() at the end will execute. That is NOT what will happen. This will actually be an infinite loop and the console.log() statement will never be executed.

The issue is that once you go into the spin wait in the while() loop, NO other Javascript can execute. So, the timer that wants to change the value of the done variable cannot execute. Thus, the while loop condition can never change and thus it is an infinite loop.

thanks @jfriend00. Thats a great answer and just what I was looking for. I hope others will upvote it too, not that you need the rep ;)

Note
Rectangle 27 0

node.js Why does a while loop block the node event loop?


var done = false;

 // set a timer for 1 second from now to set done to true
 setTimeout(function() {
      done = true;
 }, 1000);

 // spin wait for the done value to change
 while (!done) { /* do nothing */}

 console.log("finally, the done value changed!");
done
false
setTimeout()
  • 1 second into the while loop spinning, the timer fires internally to the JS engine and the timer callback is added to the event queue. This likely occurs on a different thread, internal to the JS engine.
  • Get something from the event queue
  • Run whatever task is indicated and run it until it returns
  • The while loop keeps spinning because the done variable never changes. Because it continues to spin, the JS engine never finishes this thread of execution and never gets to pull the next item from the event queue.
  • When the above task is done, get the next item from the event queue

@marshalcraft - ANY loop in Javascript blocks. Javascript is single threaded and event driven so as long as a loop is running, nothing else except the code in the loop can run. And, it's not just loops. Any long running function keeps other things from running. Single threaded - Javascript can only do one synchronous thing at a time. All loops are synchronous. In case you missed it, the summary is in my third paragraph after it explains how the event queue works (which is the key to understanding all this). I don't think that's a very long run around the bush.

Here's a simple example that might help explain it:

Here's what happens internally inside the JS engine:

I apologize jftiend. I was over critical. So non asynchronous functions block. But really a while loop in a asynchronous function would still block. Seems a while loop from start to exit is a single unit of asynchronous execution. I understand js is single threaded. But it doesn't necessarily execute code inline, so it pauses in some cases to continue asynchronous code, or events. Being as it doesn't use time to dictate how much to execute, it must use "atomic" or basic units of execution. Like run global scope code for a little, pause to handle event or do some work on asynchronous function.

If at some point, there is nothing in the event queue, then go to sleep until something is placed in the event queue.

It is conceivable that the js interpreter or runtime could do this on one thread. Also forgive my probably poor js verbage and terminology. I'm not strong with js.

It's fairly simple really. Internally, node.js consists of this type of loop:

So I get a very long run around the bush that while loops block in js.

So, if a piece of Javascript is sitting in a while() loop, then that task is not finishing and per the above sequence, nothing new will be picked out of the event queue until that prior task is completely done. So, a very long or forever running while() loop just gums up the works. Because Javascript only runs one task at a time (single threaded for JS execution), if that one task is spinning in a while loop, then nothing else can ever execute.

Some might logically think that the while loop will spin until the timer fires and then the timer will change the value of done to true and then the while loop will finish and the console.log() at the end will execute. That is NOT what will happen. This will actually be an infinite loop and the console.log() statement will never be executed.

The issue is that once you go into the spin wait in the while() loop, NO other Javascript can execute. So, the timer that wants to change the value of the done variable cannot execute. Thus, the while loop condition can never change and thus it is an infinite loop.

thanks @jfriend00. Thats a great answer and just what I was looking for. I hope others will upvote it too, not that you need the rep ;)

Note