2

In the code below, the delay for 2 is 0secs, So why does it outputs 2 after 3 and not before it?

(function() {
    console.log(1); 
    setTimeout(function(){console.log(2)}, 0); 
    console.log(3);
})();
ShawnOrr
  • 1,249
  • 1
  • 12
  • 24
Nayereh Rasuli
  • 216
  • 2
  • 8
  • I strongly suggest you to watch [Jakes talk](https://www.youtube.com/watch?v=cCOL7MC4Pl0&ab_channel=JSConf) about the event loop ([MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop)) – metodribic Oct 23 '21 at 08:44

4 Answers4

3

It will execute in the following matter:

1 3 2

setTimeout is implemented in a way it's meant to execute after a minimum given delay, and once the browser's thread is free to execute it. so, for an example, if you specify a value of 0 for the delay parameter and you think it will execute "immediately", it won't. it will, more accurately, run in the next event cycle (which is part of the event loop - concurrency model which is responsible for executing the code).

So, the printing of 1 and 3 will actually by pushed to the call stack and will execute immediately where as the setTimeout call back function will only be available to be pulled from the event queue to be picked in the next event loop tick.

Please read reason for delays longer then specified - https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified

More about the JS event loop - https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

Ran Turner
  • 14,906
  • 5
  • 47
  • 53
2

setTimeout() doesn't delay everything called after it; it only delays the function within. So it starts a timer for console.log(2), continues with the remaining code, console.log(3), and then runs the timeout function when the timer runs out.

mykaf
  • 1,034
  • 1
  • 9
  • 12
1

setTimeout(() => console.log(2), 0) is not the same thing as running console.log(2). The system is a little bit more complex, but the main idea is that you have an Event Loop that manages callbacks from two main, big queues called: callback queue and microtask queue respectively. This Event Loop is constantly keeping track of whether the call stack is empty and if we have callbacks in the callback queue to be processed. Only when the call stack is done executing all the top level code, the Event Loop takes whatever resides in the callback queues and runs it as a simple function in the call stack.

Let's go through your example line by line and see how the call stack gets populated. The first thing pushed into the stack is the global execution context with the top level code. Now your function is IIFY, which means will run immediately when the script is loaded.

(</empty/>) 

(global execution context)

callback queue -> </empty/>

  1. When function() is loaded we have
(function() execution context) 

(global execution context)

When the function execution context runs line by line it will output 1, then pushes the callback of the setTimeout (which is just a console.log(2)) when the timer expires into the callback queue

callback queue -> <console.log(2)> NOTE: THE FUNCTION DIDN'T RUN IN THE MAIN CALL STACK, IT GOT ENQUEUED BY THE EVENT LOOP IN THE CALLBACK QUEUE.

After that it will run console.log(3) and the callstack will return from function execution context, and then from the global execution context. Thus, we end up with an empty call stack

(</empty/>) 

(</empty/>) 
  1. The Event loop notices that the call stack is empty so now it delegates the function callbacks stored in the callback queue inside the call stack and runs them. Final output 1 3 2
netlemon
  • 964
  • 8
  • 22
1

This selfinvoked anonymous function declaration

function (function() {
    console.log(1); 
    setTimeout(function(){console.log(2)}, 0); 
    console.log(3);
})();

is the same as if you've written

console.log(1);
setTimeout( console.log, 0, 2);
console.log(3);

and the order of logs will be the same - be it wrapped or unwrapped in an anonymous timed function - because it will be resolved during runtime, whereas the setTimeout declaration is a program, and will have to wait until the program starts execution. And it/this will be after the JITC has finished compiling your code.

Bekim Bacaj
  • 5,707
  • 2
  • 24
  • 26