HardEvent Loop & Batching💻 Output Question

Race condition — last request wins with cancelled flag

💡

Hint

This is the canonical useEffect cleanup pattern for async data fetching. Return a cleanup that sets `cancelled = true` to ignore stale responses when the component re-renders or unmounts.

What does this output?

function fetchWithCancel(id, delay) {
  let cancelled = false;
  const promise = new Promise(resolve =>
    setTimeout(() => resolve({ id, data: result-${id} }), delay)
  );
  return {
    result: promise.then(r => cancelled ? null : r),
    cancel: () => { cancelled = true; }
  };
}

let activeResult = null;

// Simulate rapid userId changes (like fast typing)
let cleanup = null;
[1, 2, 3].forEach((id, i) => {
  setTimeout(() => {
    if (cleanup) cleanup(); // cancel previous

    const { result, cancel } = fetchWithCancel(id, 20);
    cleanup = cancel;

    result.then(r => {
      if (r) {
        activeResult = r.data;
      }
    });
  }, i * 5); // each request starts 5ms apart, takes 20ms
});

setTimeout(() => console.log(activeResult), 100);

Correct Output

result-3

Why this output?

Explanation: Request 1 starts at 0ms, request 2 at 5ms (cancels 1), request 3 at 10ms (cancels 2). Only request 3 is not cancelled. It resolves after 30ms with 'result-3'.

Key Insight: This is the canonical useEffect cleanup pattern for async data fetching. Return a cleanup that sets cancelled = true to ignore stale responses when the component re-renders or unmounts.

Practice predicting output live →

66 output questions with instant feedback

💻 Try Output Quiz