← Back to Engine

The Asynchronous Event Loop


JavaScript runs on a single-threaded Call Stack, but delegates non-blocking I/O operations to Web APIs and manages execution priorities via the Event Loop.

Execution Priority Lifecycle

  1. Call Stack: Executes synchronous JS code line by line.
  2. Microtask Queue: Holds Promise .then() callbacks, queueMicrotask(), and MutationObserver. Flushed completely until empty after the stack clears, before any render or macrotask!
  3. Macrotask Queue (Task Queue): Holds setTimeout, setInterval, setImmediate, and I/O tasks. Executes one task per loop tick.

Microtask Starvation Risk

Because the Event Loop processes ALL microtasks before picking the next macrotask or updating the UI render frame, recursively queuing microtasks will lock up the main thread and freeze the browser!


The Challenge: Predictable Queue Execution Sequence

Write a function runEventLoopSequence() that queues synchronous logs, microtasks, and macrotasks to return an array matching this exact sequence:

['1-sync', '2-sync', '3-microtask', '4-microtask', '5-macrotask']