# Asynchronous JavaScript & The EVENT LOOP — From Scratch

---

> **Note:** The Call Stack will execute any execution context that enters it — no exceptions.  
> TL;DR: **The Call Stack has no timer** — it just runs what's inside it, line by line.

---

## Understanding JavaScript in the Browser

JavaScript, by design, is **single-threaded** and **synchronous**. But wait — if it's synchronous, how does it handle things like network requests, timers, or user interactions without blocking the browser?

Here’s the secret: **JavaScript alone can’t do it all.** It relies on the **browser environment** to handle tasks that would otherwise require multithreading or system-level capabilities.

### What Powers the JavaScript Runtime?

When you run JavaScript in the browser, it works hand-in-hand with:

* The **JavaScript Engine** (e.g., V8 in Chrome)
    
* The **Call Stack**
    
* The **Web APIs** (provided by the browser)
    
* The **Callback Queue**
    
* The **Microtask Queue**
    
* And the **Event Loop** (the orchestrator)
    

---

## 🔌 Web APIs: The Superpowers from the Browser

Web APIs are **not part of JavaScript**. They’re features provided by the browser — available to JavaScript via the global `window` object. Examples include:

* `setTimeout()` – scheduling tasks
    
* `fetch()` – making HTTP requests
    
* `document` – interacting with the DOM
    
* `console.log()` – printing to the dev console
    
* `localStorage` – storing data in the browser
    

While we often use these without the `window.` prefix (like `setTimeout()`), behind the scenes they are accessed as `window.setTimeout()`.

---

## 🛠️ A Simple Asynchronous Code Example

Let’s take a look at a basic async operation:

```js
console.log("Start");

setTimeout(function cb() {
  console.log("Timer expired");
}, 5000);

console.log("End");
```

### What Happens Here?

1. A **Global Execution Context (GEC)** is created and pushed to the Call Stack.
    
2. `console.log("Start")` is executed → “Start” is printed.
    
3. `setTimeout(cb, 5000)` is encountered:
    
    * The `setTimeout` Web API is triggered.
        
    * The callback `cb()` is **registered**, and a 5-second timer starts.
        
4. `console.log("End")` is executed → “End” is printed.
    
5. After 5 seconds, the timer expires — but the callback `cb()` cannot go straight to the Call Stack.
    
6. Instead, it goes to the **Callback Queue**.
    
7. The **Event Loop** checks if the Call Stack is empty.
    
8. Once the Call Stack is clear, it pushes `cb()` into it and executes → “Timer expired” is printed.
    

---

## 🔄 Event Loop & Callback Queue Explained

The **Event Loop** is the invisible mechanism that ensures JavaScript remains non-blocking.

* It constantly **monitors the Call Stack and Callback Queue**.
    
* If the Call Stack is empty and there’s something in the Callback Queue, it pushes it onto the Call Stack.
    
* This is how asynchronous code is eventually executed.
    

### Why Do We Need a Callback Queue?

Imagine a button clicked six times rapidly:

```js
document.getElementById("btn").addEventListener("click", function cb() {
  console.log("Button clicked");
});
```

Each click triggers the callback `cb()`:

* These callbacks are stored in the **Callback Queue**.
    
* The Event Loop pushes them one by one into the Call Stack when it's free.
    
* This queuing mechanism avoids chaos and maintains the execution order.
    

---

## 🧬 Promises & The Microtask Queue

Here’s where it gets interesting. Let’s consider this:

```js
console.log("Start");

setTimeout(function cbT() {
  console.log("Timeout callback");
}, 5000);

fetch("https://api.example.com").then(function cbF() {
  console.log("Fetch callback");
});

console.log("End");
```

### Step-by-Step Breakdown:

1. “Start” is logged.
    
2. `setTimeout()` registers `cbT()` with a 5-second delay.
    
3. `fetch()` initiates a network request and registers `cbF()` to be executed once the response arrives (say in 2 seconds).
    
4. “End” is logged.
    
5. After 2 seconds, `cbF()` enters the **Microtask Queue**.
    
6. After 5 seconds, `cbT()` enters the **Callback Queue**.
    
7. The Event Loop gives **priority to the Microtask Queue**:
    
    * It empties the Microtask Queue first → `cbF()` is executed.
        
    * Then it processes the Callback Queue → `cbT()` is executed.
        

**Output:**

```plaintext
Start  
End  
Fetch callback  
Timeout callback
```

---

## ⚖️ Microtask Queue vs Callback Queue

| Feature | Microtask Queue | Callback (Task) Queue |
| --- | --- | --- |
| Priority | High | Lower |
| Examples | `Promise.then()`, `MutationObserver` | `setTimeout()`, `setInterval()`, `click` handlers |
| Execution Timing | After current execution, before next task | After the current task completes |
| Risk of Starvation | High (if tasks are recursive) | Low |

**Starvation** occurs if the Microtask Queue keeps adding new tasks recursively. This can delay or completely block the Callback Queue from being processed.

---

## Common Interview Questions

### 1\. **What is the Event Loop in JavaScript?**

The Event Loop continuously checks the Call Stack and Callback/Microtask Queues. If the Call Stack is empty, it pushes the next queued task (prioritizing Microtask Queue) onto the Call Stack.

---

### 2\. **What’s the difference between Microtask Queue and Callback Queue?**

Microtasks (like `Promise.then`) are processed before tasks in the Callback Queue (`setTimeout`, DOM events). Microtasks have higher priority.

---

### 3\. **Is** `console.log()` part of JavaScript?

No. It’s part of the browser’s `console` Web API, accessed via the `window` object.

---

### 4\. **What happens if** `setTimeout` is set to `0ms`?

Even with `0ms`, the callback is queued and must wait for the Call Stack to be clear. So, it's never truly "immediate".

---

### 5\. **Why do event listeners stay in memory after code execution?**

Event listeners are registered in the Web API environment. They stay alive to respond to events unless manually removed or the page is unloaded. This is why you should remove listeners when they’re no longer needed to avoid memory leaks.

---

### 6\. **Are synchronous callbacks also handled by the Web API environment?**

No. Only **asynchronous callbacks** (like from `setTimeout`, `fetch`, etc.) are registered with Web APIs. Synchronous callbacks used with methods like `map`, `filter`, or `reduce` are handled directly by the JavaScript engine.

---

## ✅ Final Thoughts

JavaScript may be single-threaded, but with the help of the browser’s Web APIs, Callback and Microtask Queues, and the mighty Event Loop — it becomes incredibly powerful and responsive.

Mastering this internal flow will **transform your debugging skills**, **optimize your performance logic**, and give you **a major edge in interviews**.

> Stay curious. Debug deeply. Learn beyond the syntax. 🚀

---

## Best Video to learn this topic :

%[https://youtu.be/8zKuNo4ay8E?si=i3DzgybasH2K5kKb]
