🔄 Understanding JavaScript’s Event Loop: Microtasks vs. Macrotasks Explained
In JavaScript, asynchronous behavior is at the heart of everything — from UI rendering to network calls. However, understanding how the…
🔄 Understanding JavaScript’s Event Loop: Microtasks vs. Macrotasks Explained
In JavaScript, asynchronous behavior is at the heart of everything — from UI rendering to network calls. However, understanding how the event loop handles microtasks and macrotasks is essential to mastering JavaScript’s concurrency model.
Let’s take a deep dive through an example that uncovers exactly how and when JavaScript executes tasks — especially when both setTimeout and fetch complete at the same time.
let’s consider below example code snippet. Guess what will be console in browser.
setTimeout(() => {
console.log("macrotask");
}, 1000);
fetch("https://api.example.com")
.then(() => {
console.log("microtask from fetch");
});
console.log("sync code");
You might think that whichever asynchronous task finishes first gets executed first, and in many cases, that’s true. But what happens if both a setTimeout and a fetch (or any promise-based operation) complete at the exact same time — say, after 1000ms?
In that case, which one gets pushed to the call stack first.
Before understanding this, lets dive deep into some of the JS core concepts.
Key Concepts: Event Loop Architecture
Before answering that, let’s quickly clarify what’s happening inside JavaScript’s runtime.
Call Stack
The place where synchronous code runs, one line at a time.
Web APIs
Web APIs are browser-provided (or environment-provided, like in Node.js) background services that JavaScript can use to handle tasks asynchronously — outside the main thread. e.g., setTimeout, fetch, localStorage, IndexedDBetc.), these run operations outside the main JS thread.
Since JavaScript is single-threaded, long-running tasks (like network calls or timers) would block the entire page if handled directly. Web APIs solve this by:
- Taking over long-running tasks, running them in the background
- Not blocking the main thread
- Notified via callbacks or promises when done
Remember, Web APIs Are Not JavaScript. They’re available to JavaScript in the runtime environment (e.g. browser, Node.js).
Behind the scenes:
When you call fetch():
- The browser’s network stack handles the HTTP request.
- Once the response arrives, the browser’s Promise mechanism queues the
.then()in the microtask queue. - The JavaScript engine picks up the task when it’s ready.
Same with setTimeout():
- The timer is managed by the browser (not JS engine).
- After the delay, the callback is put in the macrotask queue.
Macrotask Queue:
Used for timers, UI events, and I/O callbacks. for example, setTimeout, setInterval, DOM events, etc.
Microtask Queue
These are smaller tasks that are executed after the current JavaScript execution stack is empty, but before the browser proceeds to the next macrotask. Used for Promise.then(), Promise.catch(),queueMicrotask(), and MutationObserver.
Event Loop
The orchestrator that constantly checks:
- Is the call stack empty?
- Are there microtasks? Run all of them
- Then, pick one macrotask and run it.
Event loop run will look like this: After a macrotask starts running and finishes its synchronous code, all microtasks queued during that macrotask are executed before the next macrotask is processed.
Execution Step-by-Step
At Time = 0ms
setTimeout(...)→ scheduled for 1000ms later.fetch(...)→ begins fetching (async) via Web API..then(...)attached → will move to microtask queue once fetch completes.console.log("sync code")runs immediately. ✅ Output:sync code
At Time = 1000ms
Now, both:
setTimeoutfinishes → callback goes to macrotask queuefetchresponse arrives →.then()callback goes to microtask queue
Here is the catch, when a microtask and microtask are waiting to be executed, microtask will have higher priority over macrotask.
At every tick, the event loop:
- Runs all microtasks
- Then executes one macrotask
so final output for above code snippet will be
sync code
microtask from fetch
macrotask
Understanding the event loop, and especially the distinction between microtasks and macrotasks, helps you predict asynchronous behavior in JavaScript — whether you’re optimizing performance, debugging async bugs, or writing UI logic.
Happy coding! 💻✨
메타데이터
- post_id
- 2f4cf58b0836
- slug
- understanding-javascripts-event-loop-microtasks-vs-macrotasks-explained-2f4cf58b0836
- url
- https://medium.com/@sahusuneel777/understanding-javascripts-event-loop-microtasks-vs-macrotasks-explained-2f4cf58b0836
- canonical_url
- https://medium.com/@sahusuneel777/understanding-javascripts-event-loop-microtasks-vs-macrotasks-explained-2f4cf58b0836
- author_url
- https://medium.com/@sahusuneel777
- status
- ok
- fetched_at
- 2026-07-11 23:07:18