I’m trying to wrap my head around and understand how javascript async works in single threaded browser environment.
As asynchronous we can treat both timers and xhr requests.
Now suppose I have something like below
function doStuff() {
for(var i=0; i<100000000; i++) {
// do something to make proc busy
if(i%1000 === 0) {
console.log('in for loop');
}
}
}
setTimeout(function() {
console.log('timed out')
}, 2);
doStuff();
doStuff();
doStuff();
Timer is set to really small value (2ms), so I suppose it should work as follows:
1) timer callback is queued
2) doStuff() is executed (as a whole?), it takes some time (more than those 2 ms)
3) timer callback is run as there is a moment betweet one doStuff() execution and another
4) next doStuff() is called
4) last doStuff() is called
What I see instead is that all three doStuff() things are done before timer callback fires. And it is much longer time than those 2ms. Yes, I know this time value set in setTimeout is not guaranteed.
My question is how does javascript executes code? What is the smallest, atomic block that will be executed at once before something from async queue gets invoked?
You’re wrong here:
The why is in the answer to the following question:
JavaScript uses something called an event loop. Each event loop cycle can be called a “tick”. On every tick, the interpreter checks if there are asynchronous callbacks to be executed (e.g., a
setTimeoutcallback where the timeout has already expired).All other, synchronous, operations take place within the same tick. So, on your example, the timer will be checked for expiration in the next tick, but all three calls to
doStuffare executed in the current tick. That’s why the time value passed tosetTimeoutis not guaranteed: there’s no way to know how long it will take until the next tick, so we usually say the callbacks will run “as soon as possible”. In the case ofsetInterval, some calls may even be dropped; for example, when the next tick takes place after twice the defined interval, the callback only runs once.