Browser Event Loop vs ECMAScript Jobs

ECMAScript defines jobs and the language-level rules for executing them, while the browser host defines the larger event-loop machinery around tasks, rendering, and other environment-specific work. For frontend interviews, keep the JavaScript specification separate from browser scheduling behavior.

ECMAScript execution is organized around execution contexts and jobs. A job represents work that the ECMAScript specification requires to be processed, including promise reactions and other asynchronous language-level operations. The specification defines how jobs are enqueued and executed, but it does not prescribe the complete browser event loop.

The browser is a host environment, so it adds scheduling concepts around JavaScript. Browser APIs such as timers, DOM events, networking, and user input produce host-defined work that can eventually cause JavaScript to run. The browser's event-loop processing model also coordinates rendering opportunities and other browser activities.

A common frontend shorthand is to call these host-level units "tasks" or "macrotasks" and to call promise callbacks "microtasks." The important interview distinction is that "microtask" is primarily a host-platform scheduling concept, while ECMAScript specifies the underlying job mechanism. Browsers integrate the ECMAScript job queue with their own event-loop processing model.

After a JavaScript callback runs, pending promise reactions and other microtasks are generally processed before the browser proceeds to a rendering opportunity or the next task, subject to the host's event-loop rules. This is why a promise callback can run before a timer callback even when the timer was registered first.

For senior frontend work, avoid treating the event loop as a single queue. There are multiple layers: ECMAScript execution and jobs, browser task sources and scheduling, microtask processing, and rendering. Correct reasoning comes from identifying which layer owns each behavior.

Key points

Interview questions

What is the difference between the ECMAScript job model and the browser event loop?

ECMAScript defines jobs as units of language-level asynchronous work and specifies how they execute. The browser is a host and supplies the broader scheduling model for timers, events, networking, rendering, and other activities. Promise reactions are specified by ECMAScript and are integrated into the browser's microtask processing. Therefore, the browser event loop should not be described as if it were entirely specified by the JavaScript language specification.

Why does a resolved Promise callback usually run before a zero-delay timer?

A promise reaction is scheduled as a microtask, while a timer callback is scheduled through the browser's task machinery. After the current JavaScript execution completes, pending microtasks are processed before the event loop proceeds to a later task. Therefore the promise callback normally appears before the timer callback. A zero-millisecond timer is a scheduling request, not an instruction to interrupt the current execution immediately.

Can you explain why an infinite microtask chain can make a page unresponsive?

The browser normally drains pending microtasks before moving on to later event-loop work. If each microtask schedules another microtask, the queue can remain continuously nonempty. The browser can therefore be prevented from reaching later tasks and rendering opportunities for an extended period. This can cause input handling and visual updates to be delayed even though the JavaScript is technically executing asynchronously.

Does `setTimeout(fn, 0)` guarantee that `fn` runs immediately after the current call stack?

No. It requests that the browser schedule the callback through its timer and task mechanisms. The callback cannot interrupt currently executing JavaScript, and other required scheduling work can occur before it runs. A zero delay is therefore not a guarantee of zero elapsed time.

Why is it inaccurate to say that the browser has one event-loop queue?

The browser coordinates different kinds of host work, and the specification describes multiple task sources and scheduling concepts rather than a single universal FIFO containing every callback. Microtask processing is also distinct from task selection. Rendering introduces another host concern that is not simply another JavaScript callback in the same queue. A good explanation therefore identifies the relevant scheduling layer instead of reducing everything to one queue.