Code executed by setTimeout() is called from an execution context separate from the function from which setTimeout was called. The usual rules for setting the this keyword for the called function apply, and if you have not set this in the call or with bind, it will default to the global (or window) object in non–strict mode, or be undefined in strict mode. It will not be the same as the this value for the function that called setTimeout.
Whenever you write a function in JavaScript, the JS engine creates what we call function execution context. Also, each time the JS engine begins, it creates a global execution context that holds the global objects — for example, the window object in the browser and the global object in Node.js. Both these contexts are handled in JS using a stack data structure also known as the execution stack.
So, when you write something like this:
function a() {
console.log("i am a")
b()
}
function b() {
console.log("i am b")
}
a()
The JavaScript engine first creates a global execution context and pushes it into the execution stack. Then it creates a function execution context for the function a(). Since b() is called inside a(), it will create another function execution context for b() and push it into the stack.
When the function b() returns, the engine destroys the context of b(), and when we exit function a(), the context of a() is destroyed. The stack during execution looks like this:
Take a look at below code (very commonly asked in Interview)
setTimeout(function() {
console.log("Print 1")
}, 0)
console.log("Print 2")
setTimeout(function() {
console.log("Print 3")
}, 2000)
console.log("Print 4")
Output will be as below , note “Print 2” and “Print 4” will be before “Print 1” even though I passed ‘0’ as the dealay timer in setTimeout()
Print 2
Print 4
Print 1
Print 3
Even I can try omitting the delay completely
setTimeout(function() {
console.log("Print 1")
})
console.log("Print 2")
setTimeout(function() {
console.log("Print 3")
}, 2000)
console.log("Print 4")
It would still give me below
Print 2
Print 4
Print 1
Print 3
Explanation –
Even with a 0 millesecond delay, the asynchronous message will be displayed after the synchronous message. This is because any function given to the setTimeout function will be executed asynchronously, when the main thread is not busy anymore.
Invoking setTimeout with a callback, and zero as the second argument will schedule the callback to be run asynchronously, after the shortest possible delay.
JavaScript is single-threaded. If some block of code uses execution thread, no other code can be executed. This means your setTimeout() call must wait until main execution finishes.
Code executed by setTimeout() is called from an execution context separate from the function from which setTimeout was called. The usual rules for setting the this keyword for the called function apply, and if you have not set this in the call or with bind, it will default to the global (or window) object in non–strict mode, or be undefined in strict mode. It will not be the same as the this value for the function that called setTimeout.
What actually happens is that an event is pushed onto the event queue that’s set to execute in the number of milliseconds specified by the second argument to SetTimeout/SetInterval. The consequence of this is that if you request a 1000ms delay, then 1000ms is the MINIMUM delay you’ll get. If the execution engine is busy doing something else when the 1000ms delay is over then it will have to wait until it’s done with what it’s doing.
Since JavaScript can only ever execute one piece of code at a time (due to its single-threaded nature) each of these blocks of code are “blocking” the progress of other asynchronous events. This means that when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest completing) it gets queued up to be executed later.
setTimeout and setInterval are the only native functions of the JavaScript to execute code asynchronously. However, if you are familiar with JavaScript, you have probably dealt with asynchronous execution in various forms. It can happen in multiple situations (non-exhaustive list):
Performing an HTTP request Any I/O operation when you are in a NodeJS environment Dealing with a WebSocket (client or server side)
What does asynchronous mean (Is setTimeout asynchronous)
YES it is.
setTimeout(function(){…}, 0) simply queues the code to run once the current call stack is finished executing.
So yes, it’s asynchronous in that it breaks the synchronous flow, but it’s not actually going to execute concurrently/on a separate thread.
To further clarify, there’s a difference between concurrency/backgrounding and asynchronous-ness. When code is asynchronous that simply means it isn’t executed sequentially.
Again – From MDN setTimeout(): – “Code executed by setTimeout() is run in a separate execution context to the function from which it was called”.
But does this mean it executes in parallel to any other code that is currently in process?
No, it doesn’t. “Execution context” doesn’t mean “thread”. setTimeout code has absolutely no parallelism going on inside it. The “separate execution context” mentioned in the documentation just means that the this reference will be different than in the function where setTimeout() is called. A Javascript engine simply processes a queue of events sequentially on a single thread. When the event queue is empty, that thread idles. In a browser, events are added to the queue by user input, page loading, etc. In node.js events can also be HTTP requests or hardware events. And setTimeout() simply adds another kind of event with the additional condition that it should only be added to the queue after a certain time has passed.
One of Javascript’s strength is the way it handles asynchronous (async) code. Instead of getting blocked, the thread is pushed in an event queue which gets fired after the execution of all the other codes. This means that you can let your code do several things at the same time without stopping or locking your main thread.
Console.log( “a” );
setTimeout(function () {
Console.log( “c”)
}, 500 );
setTimeout(function () {
Console.log( “d” )
}, 500);
setTimeout(function () {
Console.log( “e” )
}, 500);
Console.log( “b” );
The code above will result with the console displaying “a” and “b” first, then after 500 milliseconds, “c”, “d” and “e” will be displayed.
Note that a timeout will only be executed after all the code in a block has finished executing. If a long-running function is set before the timeout then the function will have to finish executing first before the setTimeout function gets executed.
Basically, async functions like setTimeout and setInterval are pushed into a special queue known as the “event loop”.
The Event Loop – Its a first-in-first-out task queue, or FIFO Queue.
The event loop is a special queue for callback functions. When an async code is executed, a callback is then pushed into the queue. The Javascript engine will only execute the event loop if the code after the async function has finished executing. This is because, Javascript is single threaded.
The event loop is a first-in-first-out type of queue – callbacks are processed in order they were added to the queue.
The Call Stack – Its a LIFO data structure .
The event loop (Which on the other hand is FIFO) continuously checks the call stack to see if there’s any function that needs to run.
While doing so, it adds any function call it finds to the call stack and executes each one in order.
JavaScript has a single call stack in which it keeps track of what function we’re currently executing and what function is to be executed after that. But first — what’s a stack? A stack is an array-like data structure but with some limitations — you can only add items to the back and only remove the last item. Another example is a pile of plates — you put them on top of each other and at any time you can only remove the top one.
When you’re about to execute a function it is added on the call stack. Then if that function calls another function — the other function will be on top of the first one in the call stack. When you get an error in the console you get a long message that shows you the path of execution — this is what the stack looked in that exact moment. But what if we make a request or put a timeout on something? In theory that should freeze the entire browser until it is executed so the call stack can continue? In practice however, you know that this doesn’t happen — because of the Event Table and Event Queue.
Further Reading
https://www.hiddenwebgenius.com/guides/understanding-javascripts-asynchronous-code/
https://hackernoon.com/understanding-js-the-event-loop-959beae3ac40
https://johnresig.com/blog/how-javascript-timers-work/



