33
Macrotasks and Microtasks in JavaScript
Do you get confused between why promises are executed first rather than setTimeout or setInterval? Or you messed up an interview because of this. Let's find out why this happens
First check your understanding of microtask and macrotask using an output question. So, What would be the output of this code snippet?

If you were able to answer this correctly, Congratulations! You have a good idea about event loop and, task queues. This post is not for you.
So let’s forget about microtasks and just look at this simple code snippet-
The output of code snippet would be -
Please notice that "Good Night" will be logged after at least 5 seconds. So what happens behind the scenes?
Step by Step:
Since ES6 (JavaScript Standard) was released, it turned to be a big player for async executions in JS. It provided a different way of executing async code, adding a concept called "Microtask Queue" (also called "Job Queue"). We can now call the callback queue "Macrotask Queue", and assign a new layer on top of it.
At the end of every tick of the JavaScript Event Loop, the tasks inside the microtask queue are executed. This new functionality assures us that certain async actions will be added to the microtask queue, therefore executed right after the tick, before the next task in the macro queue.
At the end of every tick of the JavaScript Event Loop, the tasks inside the microtask queue are executed. This new functionality assures us that certain async actions will be added to the microtask queue, therefore executed right after the tick, before the next task in the macro queue.

Now let’s come to queueMicrotask. This function will explicitly put a task in microtask queue. This is what happens when a promise resolves. If you chain multiple then() statements, they will all be put in the microtask queue and are guaranteed to be executed before handling control back to browser’s event loop. So if you keep queuing tasks in the microtask queue forever, your browser will become unresponsive. You can’t click a button, can’t scroll, nothing…, GIFs stop, animations stop etc. The control will never be passed to browser renderer.
Now let’s try original question again.

The output of above code snippet would be -
Step by Step Explanation:
() => {
console.log(6);
queueMicrotask(() => ..);
} is executed logging 6 on console and adding another callback to job queue.
() => console.log(7) is pushed onto stack and executed.
Now since the job queue is empty, the task queue is checked again to see if any task is pending.
So () => { console.log('interval') } is pushed onto stack and executed.
queueMicrotask(() => ..) is executed adding callback function to job queue.
console.log(4); is pushed onto stack and executed.
() => {
console.log(2);
setTimeout( () => {
console.log(3);
clearInterval(interval);
}, 0);
} is executed logging 2 on console and adding another task to task queue.
() => { console.log('interval') } is pushed onto stack and executed.
() => {
console.log(3);
clearInterval(timer);
} is executed logging 3 on console and clearing the interval.
The important points are:
33