In our program, if any setTimers are there, those will be stored in some ware and start the timer, and the timer is attached to that specific callback. After completion of the timer, the specific callback function is pushed to the callback queue. the event loop checks the callback queue, if there is any callback function is there or not, it will be pushed to the call stack and it will create an execution context, executing the code line by line.

example for events :

console.log("Start")
document.getElementById("event").addEventListener("click",()=>{
	console.log("user clicked")
})
console.log("end")

global execution context will be created and pushed to the call stack, and execute the code line by line, first "start" will be displayed on the console

after the eventListener is there, and then it will register the callback on the web API environment and attach the event to the callback function. Next line console statement, "end " will be logged in the console, then nothing more to execute, global execution will be popped from the call stack, but the attached event handler will stay in the web API environment until and unless explicitly removed the event or the browser is closed. When the user clicks on the button, then specific callback function is pushed to the callback queue.

Why do we need a callback queue, rather than it will directly pushing the callbacks from the web API environment to the call stack? It is not, it needs a callback queue because whenever the user clicks the button continuously 100 times, those 100 events are registered in the callback queue, executing one after another. If the call stack is empty after pushing the callback from the callback queue, it will pop from the callback queue. the task does not get a chance to execute for a long time; this is known as starvation.

micro task queue: this queue has higher priority; whatever functions come inside this queue will be executed first, and functions inside the callback queue will be executed later. After the completion of all functions, then only give a chance to the callback queue.

fetch method :

example :

fetch("api.shivaji.com").then(()=>console.log("data fetched.."))

callback function is registered in the web API environment, and after successfully getting data from the server, it will be pushed to the micro stack queue rather than the callback queue. the event loop monitors the call stack to see if it is empty or not; functions are pushed to the call stack.

Micro task queue.

Promise handlers.

Async function body's after await.

QueueMicroTask.

MutationObserver callback