# The Event Loop

JavaScript is a **single-threaded** language, meaning it can only do one thing at a time. However, it can perform non-blocking operations (like fetching data or waiting for a timer) using the **Event Loop**.

## 1. The Call Stack

The Call Stack is a data structure that records where in the program we are.
*   If we step into a function, we put it on the top of the stack.
*   If we return from a function, we pop it off the top of the stack.

```javascript
function multiply(a, b) {
  return a * b;
}

function square(n) {
  return multiply(n, n);
}

function printSquare(n) {
  var squared = square(n);
  console.log(squared);
}

printSquare(4);
```

## 2. Web APIs

When you call `setTimeout`, `fetch`, or DOM events, these are not part of the V8 JavaScript engine. They are **Web APIs** provided by the browser.
*   When you call `setTimeout`, the browser handles the timer.
*   When the timer finishes, the browser pushes the callback function to the **Callback Queue**.

## 3. The Callback Queue (Task Queue)

This is a queue of callback functions waiting to be executed.

## 4. The Event Loop

The Event Loop has one simple job: to monitor the Call Stack and the Callback Queue.
1.  If the Call Stack is **empty**, it takes the first event from the queue and pushes it onto the Call Stack, which effectively runs it.

```javascript
console.log('Start');

setTimeout(() => {
  console.log('Callback');
}, 0);

console.log('End');

// Output:
// Start
// End
// Callback
```

Even though the timeout is 0, the callback is pushed to the Web API, then the Queue. The Event Loop must wait for the stack (containing `console.log('End')`) to clear before pushing the callback onto the stack.

## 5. Microtasks vs. Macrotasks

There are actually two queues:
1.  **Macrotask Queue (Task Queue):** `setTimeout`, `setInterval`, I/O.
2.  **Microtask Queue:** Promises (`.then`/`.catch`/`.finally`), `queueMicrotask`, `MutationObserver`.

**Priority:** The Event Loop prefers the Microtask Queue. It will process **all** microtasks before moving on to the next macrotask.

```javascript
console.log('Start');

setTimeout(() => {
  console.log('Timeout (Macrotask)');
}, 0);

Promise.resolve().then(() => {
  console.log('Promise (Microtask)');
});

console.log('End');

// Output:
// Start
// End
// Promise (Microtask)
// Timeout (Macrotask)
```

[[programming/javascript/vanilla/javascript]]
[[programming/asynchronous-programming]]