Skip to content
Frontend

JavaScript Event Loop: Predict the Output, Then Explain It

An event-loop question becomes easier when you track what is running and what has only been scheduled. Work through these two exercises before reading their output. The examples use browser-compatible JavaScript and focus on promises, queueMicrotask, timers, and await; Node-specific APIs such as process.nextTick are outside this exercise.

By Published

4 min readEditorial analysisUpdated
  • JavaScript
  • event loop
  • microtasks
  • interview practice
What to remember

Finish synchronous execution, then drain the microtask queue—including microtasks added while it drains. A timer callback cannot interrupt that work. Track enqueue order instead of memorizing a priority list of API names.

Exercise 1: a promise, a nested microtask, and a timer

Run this as a single script in a fresh browser page, or paste the whole block into the console. Before executing it, write six output lines and a separate list of pending microtasks. setTimeout schedules a later task; it does not make its callback run immediately just because the delay is zero.

The exact output is: start → end → promise → microtask → nested → timer. The first promise callback and the explicit microtask are already queued when synchronous code finishes. The nested callback joins the tail only when the promise callback executes.

console.log('start');
setTimeout(() => console.log('timer'), 0);
Promise.resolve().then(() => {
  console.log('promise');
  queueMicrotask(() => console.log('nested'));
});
queueMicrotask(() => console.log('microtask'));
console.log('end');

Trace the queue after each scheduling step

Treat this table as a debugging worksheet. The running callback is no longer in the pending queue. When promise executes, microtask is already waiting, so nested goes behind it. There is no general rule that every promise callback outranks every queueMicrotask callback.

The HTML event-loop model has task queues and rendering opportunities. This small example has one timer and no competing event sources, so its output is deterministic. It does not establish a universal ordering between unrelated network, input, and timer events, or guarantee a paint after each callback.

Queue state for exercise 1
AfterPending microtasksOutput so far
Synchronous scriptpromise, microtaskstart, end
promise callbackmicrotask, nestedstart, end, promise
microtask callbacknestedstart, end, promise, microtask
nested callbackemptystart, end, promise, microtask, nested
timer callbackemptystart, end, promise, microtask, nested, timer

Exercise 2: does await 0 suspend the function?

Yes. Calling an async function starts its body synchronously, but reaching await suspends that function's continuation even when the value is not a pending promise. The caller continues running. In this example, the continuation is queued before the later queueMicrotask call.

The output is script:start → review:start → script:end → review:resume → queued. Move queueMicrotask above review() and predict the last two lines again: queued now comes before review:resume. That one-line change tests whether you understand scheduling order rather than the original answer.

async function review() {
  console.log('review:start');
  await 0;
  console.log('review:resume');
}
console.log('script:start');
review();
queueMicrotask(() => console.log('queued'));
console.log('script:end');

Give an interview answer that survives a follow-up

Start by naming the execution environment, then walk through the synchronous calls. Mark where each callback is enqueued, and distinguish calling a function from scheduling its continuation. Finally, show the queue after every callback that schedules more work. This gives the interviewer a checkable explanation even if you make a small transcription mistake.

A useful follow-up is to replace the nested microtask with another timer. In that version, nested is no longer part of the same microtask checkpoint. Another is to ask what happens when a microtask keeps adding itself: it can delay subsequent tasks and rendering indefinitely. Do not run an unbounded version in your working browser tab.

  • An async function's code before its first await still runs synchronously.
  • A zero-delay timer means eligible later, not execute now or exactly zero milliseconds later.
  • Promise callbacks and queueMicrotask callbacks follow their enqueue order in these examples.
  • Rendering is scheduled by the browser; this trace is not a frame-rate model.

Turn the trace into a short review session

Save the code without its answer. On the next review, reconstruct the output and explain the two moments that change the queue: entering the promise callback and reaching await. Then make one change and predict the new output before running it. A flashcard that only asks for six memorized labels misses the mechanism.

Use the JavaScript question set for broader follow-ups about promises and the runtime. RecallDeck adds scheduled recall of interview concepts; keep the actual code execution in your editor or browser alongside that practice.

Quick answers

Frequently asked questions

Do promises always run before setTimeout?

In the first exercise, the already-scheduled promise reaction runs before the timer callback. A promise that settles later is a different case: a timer may execute before that promise has any reaction ready to run.

Is queueMicrotask faster than Promise.then?

This exercise explains ordering, not a performance benchmark. Both schedule microtask work here; choose the API for its semantics, including how errors are reported.

Can I apply the same answer to Node.js?

These examples also use APIs available in Node.js, but do not generalize the trace to process.nextTick, setImmediate, I/O phases, or module-context differences without examining Node's scheduling rules.

Source notes

References and review policy

Information checked on October 21, 2026. Section links identify sources for factual claims and technical explanations. Interpretations, practice scenarios and preparation recommendations are RecallDeck’s editorial work.

From reading to recall

Practice the full interview loop.

RecallDeck schedules the concepts you miss and keeps coding, design, and behavioral fundamentals available when the interviewer changes direction.

Start studying

Keep going