Skip to content

Quiz: Promise Chain Output Challenge

advanced15 min read

The Promise Gauntlet

Time to battle-test your async mental model. These 10 challenges are ordered by difficulty — the first few warm you up, and by the end you'll be tracing through microtask queues in your sleep.

The rules: predict the exact console output before checking. Write it down. Walking through the execution step by step is the only way to build a reliable mental model. Guessing teaches you nothing.

Let's go.


Challenge 1: The Warmup

console.log('A');
Promise.resolve().then(() => console.log('B'));
console.log('C');
Quiz
What is the output?

Challenge 2: Chained Thens

Promise.resolve(1)
  .then(val => {
    console.log(val);
    return val + 1;
  })
  .then(val => {
    console.log(val);
    return val + 1;
  })
  .then(val => {
    console.log(val);
  });

console.log('sync');
Quiz
What is the output?

Challenge 3: Promise.resolve vs new Promise

console.log('1');

new Promise(resolve => {
  console.log('2');
  resolve();
  console.log('3');
}).then(() => {
  console.log('4');
});

console.log('5');
Quiz
What is the output?

Challenge 4: Interleaved Microtasks

Promise.resolve().then(() => {
  console.log('A');
  Promise.resolve().then(() => console.log('B'));
});

Promise.resolve().then(() => {
  console.log('C');
  Promise.resolve().then(() => console.log('D'));
});
Quiz
What is the output?

Challenge 5: async/await Desugaring

async function foo() {
  console.log('foo start');
  await bar();
  console.log('foo end');
}

async function bar() {
  console.log('bar');
}

console.log('script start');
foo();
console.log('script end');
Quiz
What is the output?

Challenge 6: Error Propagation

Promise.resolve()
  .then(() => {
    console.log('A');
    throw new Error('oops');
  })
  .then(() => {
    console.log('B');
  })
  .catch(() => {
    console.log('C');
  })
  .then(() => {
    console.log('D');
  });
Quiz
What is the output?

Challenge 7: Promise.all Rejection Timing

const p1 = new Promise(resolve =>
  setTimeout(() => { console.log('p1'); resolve('p1'); }, 100)
);
const p2 = new Promise((_, reject) =>
  setTimeout(() => { console.log('p2'); reject('p2'); }, 50)
);
const p3 = new Promise(resolve =>
  setTimeout(() => { console.log('p3'); resolve('p3'); }, 150)
);

Promise.all([p1, p2, p3]).catch(err => console.log('caught:', err));
Quiz
What is the output?

Challenge 8: Microtask vs Macrotask Race

setTimeout(() => console.log('T1'), 0);

Promise.resolve()
  .then(() => {
    console.log('P1');
    setTimeout(() => console.log('T2'), 0);
  })
  .then(() => {
    console.log('P2');
  });

setTimeout(() => console.log('T3'), 0);
Quiz
What is the output?

Challenge 9: await in a Loop

async function run() {
  const values = [1, 2, 3];

  console.log('start');

  values.forEach(async (val) => {
    const result = await Promise.resolve(val * 10);
    console.log(result);
  });

  console.log('end');
}

run();
Quiz
What is the output?

Challenge 10: The Ultimate Puzzle

async function first() {
  console.log('1');
  await second();
  console.log('2');
}

async function second() {
  console.log('3');
  await Promise.resolve();
  console.log('4');
}

console.log('5');
first();
Promise.resolve().then(() => console.log('6'));
console.log('7');
Quiz
What is the output?

Bonus: The Trick Question

const promise = new Promise(resolve => {
  resolve(1);
  resolve(2);
  resolve(3);
});

promise.then(console.log);
Quiz
What is the output?

How Did You Score?

If you got 8+ right on first try, your async mental model is solid. If you missed a few, trace through them again — the act of walking through the execution step by step is what builds the neural pathways.

The patterns that trip people up most:

  • Microtasks always drain completely before any macrotask runs
  • await always yields, even for already-resolved promises
  • .catch() recovers the chain — it doesn't stay rejected
  • forEach ignores async — it doesn't await callback return values
  • Promise.all rejection doesn't cancel other promises

Master these five rules and you'll never be surprised by async output again.