Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why setTimeout outputs numbers not in order added

Tags:

javascript

I have the following code:

function wait(ms) {
    var start = +(new Date());
    while (new Date() - start < ms);
}

(function() {
    setTimeout(function(){console.log(2)}, 1000);
    setTimeout(function(){console.log(3)}, 0);
    setTimeout(function(){console.log(4)}, 0);
    wait(2000); //!!! blocking events processing here
})();

It outputs:

3
4
2

I've read somewhere that setTimeout adds function to the event queue, and then when this function is the first in the chain it checks whether the specified amount of time has passed, if not, it postpones execution. Under this logic I expected the above code to output: 2,3,4 since wait() function blocks event chaining processing and a call stack completes and a browser finally has time to process functions added through setTimeout, all three functions are placed in the queue in the order added and 1000 have already passed for the first function, so a browser can take it and execute, but it waits for the functions added second and third. Why? Where is the error in my logic?

like image 596
Max Koretskyi Avatar asked Apr 05 '16 08:04

Max Koretskyi


1 Answers

The callback function enters the queue after the timeout period. So,

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

enters immediately, but

setTimeout(function(){console.log(2)}, 1000);

enters the queue after 1 second. Hence the order 3,4,2

From MDN:

Calling setTimeout will add a message to the queue after the time passed as second argument. If there is no other message in the queue, the message is processed right away; however, if there are messages, the setTimeout message will have to wait for other messages to be processed. For that reason the second argument indicates a minimum time and not a guaranteed time.

(emphasis mine)

like image 194
T J Avatar answered Oct 20 '22 05:10

T J