I know that javascript is single threaded and run one task or statement at a time. But the Run to Completion nature of javascript is really making me confused. I have the following piece of code:
console.log('1');
setTimeout(function() {
console.log('2');
setTimeout(function() {
console.log('3');
},0);
},0);
console.log('5');
I expected the output to be following:
1
2
3
5
But it is giving
1
5
2
3
How it is behaving like this even if I've zero millisecond in all the timers. So it should execute one after one without waiting for anything because of zero millisecond.
Could anybody please explain this thing to me. Really appreciate.
I know that javascript is single threaded and run one task or statement at a time. But the Run to Completion nature of javascript is really making me confused. I have the following piece of code:
console.log('1');
setTimeout(function() {
console.log('2');
setTimeout(function() {
console.log('3');
},0);
},0);
console.log('5');
I expected the output to be following:
1
2
3
5
But it is giving
1
5
2
3
How it is behaving like this even if I've zero millisecond in all the timers. So it should execute one after one without waiting for anything because of zero millisecond.
Could anybody please explain this thing to me. Really appreciate.
Share Improve this question edited Jul 22, 2016 at 6:56 Manish Jangir asked Jul 22, 2016 at 5:28 Manish JangirManish Jangir 5,4376 gold badges48 silver badges78 bronze badges 3- Have a look at this page. ejohn/blog/how-javascript-timers-work – simonv Commented Jul 22, 2016 at 5:41
- I had the same question and I found this book, I really liked it: packtpub./web-development/javascript-concurrency – cstuncsik Commented Jul 22, 2016 at 5:46
- I would expect the output to be 1, 5, 2, 3. I don't know where you're getting 4 from... – nnnnnn Commented Jul 22, 2016 at 5:50
1 Answer
Reset to default 10To understand this you will have to be familiar with two javascript concepts
Queue
A JavaScript runtime contains a message queue, which is a list of messages to be processed. A function is associated with each message. When the stack is empty, a message is taken out of the queue and processed. The processing consists of calling the associated function (and thus creating an initial stack frame). The message processing ends when the stack bees empty again.
Adding tasks to the queue
Calling setTimeout will add a message to the queue after the time passed as a 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.
So every synchronous code takes priority of execution over any asynchronous code that gets pushed to a stack of tasks to be executed after everything synchronous finishes
so your code will be executed as such
- log 1
- Push to the stack the function of the outer most setTimeout (1)
- Log 5
- finishes synchronous code
- Pop function added to queue (1) for execution
- Log 2
- Push to the stack the function of the inenr most setTimeout (2)
- finishes synchronous code
- Pop function added to queue (2) for execution
- Log 3
You can read more about it in MDN article for Event Loop in Javascript
note: there is no console.log(4) in your code
note 2: the execution order above assumes your entire script is the one provided and no other timeouts are pending from code not shown