Callbacks and the Event Loop

A callback is a function you pass to other code to call later: array.map(fn) calls it synchronously, while setTimeout(fn) and addEventListener("click", fn) call it after your current code finishes. The engine (V8 86,723 , SpiderMonkey 946,470 , JavaScriptCore) runs code on a call stack; the host (the browser, or Node.js 2,131 with libuv) waits for timers, sockets and disks, often on other threads, and queues your callback when the result is ready. The event loop picks what runs next.

The browser event loop: one task, then every microtask, then an optional rendering update
The browser event loop: one task, then every microtask, then an optional rendering update

A task runs to completion, so while your code is busy nothing else happens: no timer, no click, no repaint.

A busy loop delays a zero-millisecond timerJavaScriptLive
const start = performance.now();
setTimeout(() => console.log(`0 ms timer ran after ${Math.round(performance.now() - start)} ms`));
while (performance.now() - start < 200) {}      // 200 ms of work blocks the call stack
console.log("busy loop done");

The setTimeout() delay (Timers) is only a minimum. Browsers flag tasks of 50 ms or more as long tasks (Long Tasks API, DevTools Performance panel) because they delay input. Split heavy work into chunks separated by timers, or move it to a Web Worker (Web APIs), which has its own event loop. Node.js runs the same model in phases: timers, I/O polling, setImmediate() checks and close callbacks.