javascriptadvanced10 minutes

Predict the Output of Complex Closure and Async Workflows in JavaScript

Analyze a JavaScript code snippet combining closures, async/await, Promises, and loops, then predict the exact order and content of its console output.

Challenge prompt

Examine the following JavaScript code that uses nested functions, closures, async/await, and Promise-based delays. Predict exactly what strings will be logged to the console and in which order, after the function runSequence() is invoked.

Guidance

  • Focus on understanding how closures capture variables in loops.
  • Consider the effects of async/await with Promise delays within loops.
  • Remember the event loop behavior and microtask queue processing order.

Hints

  • Variables declared with var inside loops can cause unexpected captures due to function scoping.
  • The await keyword pauses execution within async functions but does not block the main thread.
  • Promises resolved inside loops execute their .then() callbacks as microtasks after the current call stack completes.

Starter code

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function runSequence() {
  for (var i = 0; i < 3; i++) {
    delay(10).then(() => console.log('Then', i));
    (async function(j) {
      await delay(5);
      console.log('Await', j);
    })(i);
  }
  console.log('Loop done');
}

runSequence();

Expected output

Loop done Await 0 Await 1 Await 2 Then 3 Then 3 Then 3

Core concepts

closuresasync/awaitPromiseevent loopvariable scoping

Challenge a Friend

Send this duel to someone else and see if they can solve it.