HardAsync & Effects🐛 Debug Challenge

Race condition — earlier slow request overwrites later fast one

Buggy Code — Can you spot the issue?

const log = [];
let currentResult = null;

function fakeSearch(query, delay) {
  return new Promise(resolve =>
    setTimeout(() => resolve(results for: ${query}), delay)
  );
}

// Bug: no cancellation — fast response after slow can overwrite
async function search(query) {
  const result = await fakeSearch(query, query.length < 6 ? 50 : 10);
  currentResult = result; // always sets, even if stale
  log.push('set: ' + result);
}

search('react');        // slow (50ms) — starts first
search('react hooks');  // fast (10ms) — starts second

setTimeout(() => {
  console.log(currentResult); // race condition: 'react' might win!
}, 100);

Fixed Code

const log = [];
let currentResult = null;

function fakeSearch(query, delay) {
  return new Promise(resolve =>
    setTimeout(() => resolve(results for: ${query}), delay)
  );
}

// Fix: request ID — only accept the latest request's result
let latestRequestId = 0;

async function search(query) {
  const requestId = ++latestRequestId;
  const result = await fakeSearch(query, query.length < 6 ? 50 : 10);

  if (requestId === latestRequestId) { // still the latest?
    currentResult = result;
    log.push('set: ' + result);
  } else {
    log.push('discarded: ' + result);
  }
}

search('react');
search('react hooks');

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

Bug Explained

Bug: 'react' (50ms) starts before 'react hooks' (10ms). 'react hooks' resolves first and sets the result. Then 'react' resolves and overwrites with stale data.

Explanation: 'react' gets requestId=1, 'react hooks' gets requestId=2 (latestRequestId). 'react hooks' resolves first — requestId(2) === latestRequestId(2), sets result. 'react' resolves — requestId(1) !== latestRequestId(2), discarded.

Key Insight: Race condition fix: increment a counter on each request, check if yours is still the latest when it resolves. AbortController is cleaner (actually cancels the request) but request ID is simpler to understand.

Practice spotting bugs live →

38 debug challenges with AI hints

🐛 Try Debug Lab