How do you handle race conditions in JavaScript?
A race condition is when the outcome depends on the unpredictable timing of async operations — e.g. a slow earlier request overwriting a newer result.
AbortController — cancel stale requests (like outdated search queries).
Track latest — ignore responses that aren't from the most recent request.
Sequencing — await in order, or use locks/queues when order matters.
Classic case: type-ahead search where an older response lands after a newer one — always honour the latest request.
// Race condition: search results arriving out of order
let lastQuery = '';
async function search(query) {
lastQuery = query;
const results = await fetch(`/api/search?q=${query}`).then(r => r.json());
if (query !== lastQuery) return; // Stale result, ignore!
displayResults(results);
}
// Better: AbortController
let controller = null;
async function searchWithAbort(query) {
controller?.abort(); // Cancel previous request
controller = new AbortController();
try {
const res = await fetch(`/api/search?q=${query}`, { signal: controller.signal });
displayResults(await res.json());
} catch (err) {
if (err.name !== 'AbortError') throw err;
}
}
// Version counter pattern
let requestVersion = 0;
async function fetchData(id) {
const version = ++requestVersion;
const data = await fetch(`/api/data/${id}`).then(r => r.json());
if (version !== requestVersion) return; // Newer request was made
updateUI(data);
}The lastQuery check ignores stale results (simple but wasteful — the request still completes). AbortController cancels the previous request entirely (saves bandwidth).
The version counter increments on each request and checks if it is still the latest before updating UI. All three prevent displaying stale data from slower, earlier requests.
AbortController is the best solution (actually cancels the request). The version counter is an alternative when cancellation is not possible.
Show the search-as-you-type scenario — it is the most relatable example. This demonstrates understanding of real-world async challenges.