In JavaScript’s concurrency model, particularly within the event loop, the concepts of macrotasks and microtasks describe **when** asynchronous code gets executed — and **in what order**.
# Core Concept
JavaScript runs on a **single thread**, meaning only one operation can happen at a time. To handle async behavior without blocking, it uses:
1. Call Stack (for currently running functions) 1. Event Loop (a scheduler) 1. Multiple **Task Queues** — primarily: * Macrotask Queue * Microtask Queue
Let’s break them down.
# Example: Macrotask vs Microtask in Action
console.log("A"); setTimeout(() => { console.log("B"); // Macrotask }, 0); Promise.resolve().then(() => { console.log("C"); // Microtask }); console.log("D");
**Output:**
A D C B
Explanation: 1. `A` and `D` run immediately (synchronous) 2. Microtask `C` runs next (before any timeout) 3. Macrotask `B` (from `setTimeout`) runs last
# 3. Other / Less Common Queues These are environment-specific or framework-related, and usually built on top of macro/microtasks:
- Rendering Queue (Browser) - IO Queue (Node.js) - Task Schedulers
# Summary: Microtask vs Macrotask | Feature | Microtask Queue | Macrotask Queue | | --------------- | ---------------------------------- | ----------------------------- | | Examples | `Promise.then`, `queueMicrotask()` | `setTimeout`, `setInterval` | | Priority | Higher | Lower | | Runs when? | After current call stack | After call stack & microtasks | | Execution order | All microtasks are drained first | One per event loop iteration | | Spec | ES6/ES2015 (PromiseJobs) | HTML5 / Node.js event loop |
# Intuition: * Use **microtasks** for critical follow-up actions (like `.then()`) * Use **macrotasks** for delayed or scheduled actions (like `setTimeout`) * Always remember: **microtasks drain first**