JavaScript is single-threaded, but it’s designed to handle asynchronous operations with grace. At the heart of this capability lies the Event Loop. Understanding the event loop, especially how microtasks and macrotasks work, is crucial for writing efficient and predictable JavaScript code. In this blog, we’ll break down the event loop, explore microtasks vs macrotasks, and explain where async/await
fits in.
JavaScript runs in a single-threaded environment. It can only do one thing at a time, yet it handles events, timers, network requests, and more asynchronously. This is thanks to the event loop.
Here’s the basic idea:
JavaScript has two types of asynchronous tasks:
Scheduled via:
Promise.then()
, catch()
, finally()
queueMicrotask()
async/await
(internally based on Promises)Run after the current call stack, before any rendering or I/O.
Scheduled via:
setTimeout
, setInterval
setImmediate
(Node.js)MessageChannel
Run after the call stack and after all microtasks.
console.log("Start");setTimeout(() => {console.log("Macrotask");}, 0);Promise.resolve().then(() => {console.log("Microtask");});console.log("End");
Output:
StartEndMicrotaskMacrotask
Even though setTimeout
is set to 0ms, the microtask from the Promise.then()
runs first. Microtasks always have higher priority.
async/await
is syntactic sugar over Promises.
async function example() {console.log("1");await Promise.resolve();console.log("2");}example();console.log("3");
Output:
132
await
pauses the example
function.console.log("2")
) is added as a microtask.console.log("3")
runs first because it’s in the main stack.Feature | Task Type | Executes When |
---|---|---|
setTimeout() | Macrotask | After current stack & microtasks |
Promise.then() | Microtask | After stack, before macrotasks |
async/await | Microtask | Awaited code resumes as microtask |
DOM Events | Macrotask | After stack & microtasks |
async/await
) for finer control and faster async execution.setTimeout
when you want to delay execution until after rendering or I/O.The JavaScript event loop is an elegant mechanism that allows a single-threaded language to handle complex asynchronous operations. Understanding the difference between microtasks and macrotasks, and how async/await
fits into this model, will make you a more confident and capable JavaScript developer.
Stay tuned for a visual deep-dive into the event loop in our next post!
Quick Links
Legal Stuff
Social Media