Ref 1 - https://www.youtube.com/watch?v=eiC58R16hb8
Ref 2 - https://javascript.info/event-loop
Ref 3 - https://whataboutcoding.com/event-loop-in-javascript/
Understanding the problem statement
Let’s have a look at the below code: –
//Code 1
console.log("start");
function func1(){
console.log("inside function")
}
func1();
console.log("end");
//output
start
inside function
end
//Code 2
console.log("start");
setTimeout(function(){
console.log("inside function")
}, 2000);
console.log("end");
//output
start
end
inside function
*The way how the above codes will execute in java scipt in completely different.*
Since JavaScript is a single-threaded language, the execution will start from top to bottom.
- In code 1 , the execution will start from top to bottom and the output will be printed as below
- In code 2 , since we have
setTimeout
i.e part of web API, the flow of execution changes and hence the o/p is as below
Adding event loop to the execution flow
- `Step 1` – As soon as js engine finds the script tag, it creates a global execution context inside the call stack.
-
Step 2
– It first encounters the log statement and prints the output “start“ -
`Step 3
– It finds the function and creates a stack of functional execution context above the global execution context. Now in the execution phase, the
setTimeout` API of the browser is pushed to WEB API’s memory. The callback of set timeout is added to WEB API’s, and a time of 2sec is attached to it. -
Step 4
– The function execution context is now popped out and since js engine is a single-threaded, the execution moves forward, and the next log statement is printed i.e “end“ -
`Step 5
– Now once the 2 sec timer is completed, the callback function is added to task queue i.e
macrotask queue` to be specific, where it will be waiting in a queue for the call stack to be empty. The task under queue is executed as first come first serve basis. -
Step 6
– Now comes the job of event loop. The main job ofevent loop
is to check if call stack is empty, and once its empty, it will push the tasks in task queue to call stack for execution. -
Step 7
– Finally the callback function of setTimeout pushed to call stack and executed. -
Step 8
– Call stack becomes empty , and the executed end.
Definition of all the jargons -
CallStack
💡
Callback keeps track of the function calls , managing their execution and maintaining the program state.
Web API’s
💡
Web APi's are the browser provided API to extend the functionality of a web browser. For eg - http/https, dom api , fetch api , event listeners api , etc .
Task Queue/Callback Queue
Task comes under task queue are typlically input events , timer events, and other event from web api's
Microtask Queue
Task comes under microtask queue are ususally associates with the promises and it has hight priority than macrotask queue.
Example - process.nextTick, Promises, queueMicrotask, MutationObserver
Macrotask Queue
This queue only executes once all the macro task queue becomes emepty. It has lowest priority.
Example - setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI Rendering
Priority of task queue
- Call Stack → executes synchronous code first.
-
Microtask Queue → handles Promises,
queueMicrotask()
, andprocess.nextTick()
(Node.js only). -
Macrotask (Callback) Queue → handles
setTimeout
,setInterval
,setImmediate
, I/O callbacks, etc.
┌────────────────────────────┐
│ Call Stack │
└────────────┬───────────────┘
│
┌─────────────▼───────────────┐
│ Web APIs │
│ (setTimeout, fetch, Events) │
└─────────────┬───────────────┘
│
┌───────┴────────┐
│ │
┌─────────▼────────┐ ┌───▼──────────┐
│ Microtask Queue │ │ Macrotask Q │
│ (Promise, qMicro) │ │ (setTimeout) │
└─────────┬────────┘ └───┬──────────┘
│ │
└───▶ Event Loop ◀───┘
🏆 Highest → Lowest Priority
Priority | Type | Example |
---|---|---|
🥇 1 |
process.nextTick() (Node.js only)
|
process.nextTick(() => ...) |
🥈 2 | Microtasks |
Promise.then() , queueMicrotask()
|
🥉 3 | Macrotasks / Callbacks |
setTimeout() , setInterval() , setImmediate() , event listeners |
Explanation
Let’s say we have a setTimeout , promises , console log and event listeners are in the call stack.
Now the question is which will be executed first.
- console.log will be executed first , as it directly executes on the call stack.
- Secondly, since promise comes under microtask queue which has the higher priority.
- Third , eventListener will be executed as it comes under the callback queue
- Fourth, setTimeout will be executed , since it’s the part of macrotask queue which has the least priority.
Questions :
ques 1 :
console.log('Start');
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
delay(1000).then(() => {
console.log('Delayed function');
});
console.log('End');
Ques 2 :
setTimeout(function () {
console.log(1);
}, 0);
console.log(2);
Promise. resolve().then(() => {
console.log(3);
});
setTimeout(function () {
console.log(4);
});
console.log(5);
Ques 3 :
console.log('Start');
setTimeout(() => {
console.log('Inside setTimeout 1');
}, 0);
new Promise((resolve, reject) => {
console.log('Inside Promise constructor');
resolve();
})
.then(() => {
console.log('Inside Promise then 1');
return new Promise((resolve, reject) => {
console.log('Inside nested Promise constructor');
resolve();
});
})
.then(() => {
console.log('Inside Promise then 2');
});
setTimeout(() => {
console.log('Inside setTimeout 2');
}, 0);
console.log('End');
Top comments (0)