# Trust Issues with setTimeout()

## **Key Concept**

> `setTimeout()` does **not guarantee** the execution of the callback **exactly after the given time** (e.g., 5000ms). It guarantees that the callback will be **executed *at least* after the given time**, but **only when the call stack is empty**.

---

## Let's Observe the Following Code:

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

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

console.log("End");
// Suppose: Millions of lines of code follow...
```

### 🧾 Output:

```plaintext
Start
End
// After ~10s (not 5s, even though timer is 5s)
Callback
```

---

## Why Does This Happen?

### 🔁 Step-by-step Execution:

1. **GEC (Global Execution Context)** is created and pushed into the **Call Stack**.
    
2. `"Start"` is printed.
    
3. `setTimeout(cb, 5000)` is encountered:
    
    * The callback `cb()` is sent to the **Web APIs** environment.
        
    * A timer of **5 seconds** starts running **independently**.
        
    * JavaScript continues immediately without waiting.
        
4. `"End"` is printed.
    
5. Suppose the remaining code after `"End"` takes **10 seconds** to execute—blocking the main thread.
    
6. Meanwhile, the timer expires in 5 seconds, and the callback is pushed to the **Callback Queue**.
    
7. However, since the **Call Stack is busy**, the **Event Loop** keeps waiting.
    
8. Only after the Call Stack is empty (after 10s), the Event Loop pushes `cb()` into the Call Stack.
    
9. Then the `cb()` is executed, printing `"Callback"`.
    

---

## Concurrency Model of JavaScript

JavaScript uses a **Concurrency Model** based on:

* **Call Stack**
    
* **Web APIs**
    
* **Callback Queue**
    
* **Event Loop**
    

📚 Learn more on [MDN: JavaScript Event Loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop)

---

## 🔥 Real-World Example (Blocking the Main Thread)

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

setTimeout(() => {
  console.log("Callback after 2s");
}, 2000);

// Simulate heavy CPU task
let startTime = Date.now();
while (Date.now() - startTime < 5000) {
  // Blocking main thread for 5s
}

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

### 🧾 Output:

```plaintext
Start
End
Callback after 2s
```

Even though the timer is 2s, it prints **after ~5s**, because the main thread is blocked.

---

## ⚠️ The First Rule of JavaScript:

> **Never block the main thread.**  
> JavaScript is a **single-threaded** language. Blocking the Call Stack means blocking **everything** — rendering, user interaction, animations, and even `setTimeout()` callbacks.

---

## What if `setTimeout(..., 0)`?

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

setTimeout(() => {
  console.log("Callback");
}, 0);

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

### 🧾 Output:

```plaintext
Start
End
Callback
```

### Why?

Even though the timer is 0ms:

* The callback still goes through the **Web APIs** → **Callback Queue** → **Event Loop**.
    
* It waits until the **Call Stack is empty**.
    
* Useful to **defer** lower-priority tasks.
    

---

## 🧰 Practical Use Case: Deferring Execution

```js
function importantTask() {
  console.log("🔥 Important Task");
}

function lessImportantTask() {
  console.log("🕓 Less Important Task");
}

// Let important task run first
importantTask();
setTimeout(lessImportantTask, 0);
```

Even though the timeout is 0, `lessImportantTask()` waits until the stack is empty.

---

## Summary

| Concept | Explanation |
| --- | --- |
| `setTimeout(fn, delay)` | Executes `fn` **at least after** `delay` ms |
| JS is single-threaded | Only one Call Stack |
| Callback delay reason | Callback waits in queue until Call Stack is empty |
| `delay = 0` | Still not executed immediately—goes through Web APIs and queue |
| Event Loop | Continuously checks if Call Stack is empty, then pulls from queue |
