Image description

JavaScript is known for its single-threaded, non-blocking nature, which is made possible by the Event Loop. Understanding how the Event Loop works is crucial for writing efficient and bug-free asynchronous code. In this post, we'll explore the Event Loop, its components, and how it manages asynchronous operations.

πŸ“Œ What is the Event Loop?

The Event Loop is a mechanism that allows JavaScript to perform non-blocking operations by offloading operations to the system kernel whenever possible. It continuously checks the call stack and the task queue, executing tasks from the queue when the stack is empty.

🧱 Components of the Event Loop

  1. Call Stack: This is where functions are pushed when invoked and popped when they return.
  2. Web APIs: Browser-provided APIs like setTimeout, DOM events, and fetch are handled here.
  3. Callback Queue (Task Queue): Functions like setTimeout and setInterval callbacks are queued here after their timers expire.
  4. Microtask Queue: Promises and MutationObserver callbacks are queued here. Microtasks have higher priority than the callback queue.

πŸ”„ How Does It Work?

  1. When a function is called, it's added to the call stack.
  2. If the function contains asynchronous operations (e.g., setTimeout), the operation is handled by the Web APIs.
  3. Once the asynchronous operation is complete, its callback is added to the appropriate queue (microtask or callback queue).
  4. The Event Loop checks if the call stack is empty. If it is, it pushes the first task from the microtask queue to the call stack.
  5. After all microtasks are processed, it moves to the callback queue and processes tasks there.

Example:

setTimeout(() => {
  console.log('Timeout');
}, 0);

Promise.resolve().then(() => {
  console.log('Promise');
});

console.log('End');

Output:

Start
End
Promise
Timeout

Explanation:

  • 'Start' and 'End' are logged immediately.
  • The Promise callback is a microtask and is executed after the current call stack is empty.
  • The setTimeout callback is a macrotask and is executed after microtasks.