To understand how JS handles multiple tasks, we have to look at the three main components working together:
setTimeout, fetch, and DOM events.The Event Loop has one simple job: Monitor the Call Stack and the Callback Queue.
Not all tasks are created equal. JavaScript prioritizes certain tasks over others.
Includes: setTimeout, setInterval, setImmediate, and I/O tasks.
Includes: Promises (.then, .catch, .finally) and MutationObserver.
The Golden Rule: The Event Loop will empty the entire Microtask Queue before moving on to the next Macrotask. This is why Promises always run before
setTimeout.
When you run a setTimeout, JavaScript doesn’t “wait” for the timer.
Since JS is single-threaded, if you run a heavy mathematical calculation or a very long loop, you “block” the Call Stack. The Event Loop cannot check the queues, meaning the browser freezes—you can’t click buttons or scroll.
Example of Blocking Code:
JavaScript
console.log("Start");
// A heavy loop that takes 5 seconds
for (let i = 0; i < 1000000000; i++) {}
console.log("End");
// The browser will be frozen until "End" is printed.
Predict the output of the code below to see if you understand the queue priorities:
JavaScript
console.log("1: Script Start");
setTimeout(() => {
console.log("2: SetTimeout (Macrotask)");
}, 0);
Promise.resolve().then(() => {
console.log("3: Promise (Microtask)");
});
console.log("4: Script End");
Correct Output:
1: Script Start (Synchronous)4: Script End (Synchronous)3: Promise (Microtask) (Microtasks have priority!)2: SetTimeout (Macrotask) (Runs only after Microtasks are clear)Modern applications must handle:
All of this happens without blocking the main thread.
The Event Loop is the engine behind non-blocking, asynchronous execution.
Concurrency is the ability to manage multiple tasks at the same time, even if they are not executed simultaneously.
| Concurrency | Parallelism |
|---|---|
| Task switching | Multiple cores |
| Single thread possible | Requires multiple threads |
| I/O focused | CPU focused |
JavaScript (and Node.js) is:
Only one call stack, but many tasks are handled via the event loop.
setTimeoutsetIntervalExamples:
then, catch)queueMicrotaskMutationObserverPriority:
| API | Behavior |
|---|---|
| setTimeout | Executes after delay |
| setInterval | Repeated execution |
| setImmediate (Node) | After I/O |
| requestAnimationFrame | Before repaint |
Microtasks run between phases.