call(back)

Predict the Output: Promise and Timer Order

What does this log, and in what order? Explain why.

const p = new Promise((resolve) => {
  console.log(1);
  setTimeout(() => {
    resolve();
  });
});

Promise.resolve().then(() => console.log(2));
setTimeout(() => console.log(3));
p.then(() => console.log(4));
setTimeout(() => console.log(5));

Hints

Hint 1

Sort each callback into one of two queues. Timers are tasks; promise callbacks and the code after an await are microtasks. After each task, every waiting microtask runs before the next task starts.

Hint 2

The executor passed to new Promise runs synchronously.

Solution

Show the approach

Answer: 1, 2, 4, 3, 5

The executor runs synchronously, so 1 prints first. When the script ends, the microtask queue runs and prints 2. The first timer then resolves p, which queues its then callback as a microtask. Microtasks drain after every task, so 4 prints before the next timer prints 3.

The loop in three steps: run one task (the script, a timer callback, an event handler), drain all microtasks (then, catch and finally callbacks, code after an await, queueMicrotask), render if a frame is due, then take the next task.

Asked at