MediumEvent Loop & Batching💻 Output Question

Promise chain order inside useEffect

💡

Hint

In useEffect with async code, the synchronous part runs immediately after render. Promise resolutions run as microtasks. State updates from async code still trigger re-renders.

What does this output?

const log = [];

// Simulates an async useEffect
function simulateEffect() {
  log.push('effect start');

  Promise.resolve('data')
    .then(data => {
      log.push('data received: ' + data);
      return data.toUpperCase();
    })
    .then(upper => {
      log.push('set state: ' + upper);
    });

  log.push('effect end (sync part)');
}

simulateEffect();
log.push('after effect setup');

setTimeout(() => console.log(log.join(' | ')), 10);

Correct Output

effect start | effect end (sync part) | after effect setup | data received: data | set state: DATA

Why this output?

Explanation: The synchronous parts run first (effect start, effect end, after effect). Promise .then callbacks run as microtasks — after sync but before setTimeout.

Key Insight: In useEffect with async code, the synchronous part runs immediately after render. Promise resolutions run as microtasks. State updates from async code still trigger re-renders.

Practice predicting output live →

66 output questions with instant feedback

💻 Try Output Quiz