How JS Handles Everything
JavaScript is single-threaded — it executes one piece of code at a time. So how can it handle network requests, timers, and user clicks without freezing? The answer is the Event Loop and its two task queues.
The Two Queues
Macrotasks (Normal Priority)
setTimeoutandsetIntervalcallbacks- DOM events (
click,mousemove, etc.) - Network response callbacks
- Page rendering
Microtasks (High Priority)
- Promise handlers (
.then,.catch,.finally) awaitcontinuationsqueueMicrotask()
The Event Loop Algorithm
- Execute the current synchronous code (the first " macrotask " ).
- Execute ALL pending microtasks (empty the entire microtask queue).
- Render the page if needed.
- Execute the next ONE macrotask from the queue.
- Repeat from step 2.
console.log('1 - Sync');
setTimeout(() => console.log('3 - Macrotask (setTimeout)'), 0);
Promise.resolve()
.then(() => console.log('2 - Microtask (Promise)'));
// Output: 1 → 2 → 3
Note
Microtasks have priority. If a promise handler creates ten more promises, the browser won't render or process any macrotask until ALL those microtasks are finished.