Understanding Event Loop in JavaScript

JavaScript is a synchronous, single-threaded language. It can only execute one line at a time.

Call Stack:

The Call stack is a Last In First Out data structure and it is where all the code gets executed. This maintains the order of execution.

Global Execution Context:

Everything in JavaScript executes inside the Global Execution Context. Global execution Context is created in two phases:

Memory Creation Phase:

Memory allocation of variables and functions happens in this phase. Once the variable is created, the value will be assigned as undefined (just a temporary placeholder) and all the functions will point to its code. Due to this phase, you can access all the variables in JavaScript even before you have initialized it and it will not throw any error. This concept is popularly called Hoisting.

Code Execution Phase:

All the variable values are initialized according to their assignments and code will be executed in this phase

Whenever a function is invoked, a brand new execution context and lexical environment are created. The lexical environment is the local memory along with the lexical environment of a parent.

Once all the code execution is completed, the global execution context will be deleted.

Javascript Web APIs:

There are different APIs provided by the Web Browser like setTimeout(), setInterval(), clearTimeout(), clearInterval(), etc that help to perform additional tasks that cannot be run using the main thread.

Callback Queue ( Task Queue / Macro Task Queue )

When the browser is done with the timer (executed by Web APIs), it doesn't transfer the callback function to the call stack immediately instead it will send the callback function to the callback queue.

The Callback queue keeps track of all the function queues, which are needed to be pushed into the call stack. The queue data structure is required to maintain the correct sequence in which all operations should be sent for execution.

Microtask Queue:

Microtask Queue is like the Callback Queue but Microtask Queue has higher priority. All the callback functions coming through Promises and Mutation Observer will go inside the Microtask Queue.

Event Loop:

The event loop continuously monitors the call stack and callback queue/microtask queue. If the call stack is empty and if the event loop sees the function that is waiting to be executed in the callback queue, the event loop just takes that function and puts it in the call stack then the callback function will be quickly executed. It specifically manages the execution of asynchronous callbacks.