A search that shows a stale result
Task: after a new phrase is typed, an older request sometimes finishes later and overwrites the result. Fix that, and handle errors and the component unmounting. First explain the problem with two requests, without writing code.
Tests: effects, state, closures and asynchronous work.
The tests cover the isolated logic; they don't test a running React component. Write createLatestSearch(load, publish), which returns { search(query), dispose() }. load(query, signal) returns a Promise, and publish receives {status: 'success', value} or {status: 'error', error} — only for the latest, uncancelled query, even when the API ignores abort. A React component using the same approach is in the reference materials.
Follow-up: what about after unmounting, or when the cancellation signal is ignored?
You will practise
- Recognise a race between two requests
- Mark which response is still current
- Cancel the previous request
- Don't publish state after dispose
The 2 tests
Tests ported from the source material's reference.test.ts (node:test). In the browser they run with the same set of assertions.
search: an older success doesn't overwrite a newer one, even when abort is ignored
const a = deferred(), b = deferred(), seen = [];
const s = createLatestSearch(q => q === 'a' ? a.promise : b.promise, x => seen.push(x));
const p = s.search('a'), q = s.search('b');
b.resolve('new'); await q; a.resolve('old'); await p;
assert.deepEqual(seen, [{ status: 'success', value: 'new' }]);search: an old error and dispose don't publish state
const a = deferred(), b = deferred(), seen = [];
const s = createLatestSearch(q => q === 'a' ? a.promise : b.promise, x => seen.push(x));
const p = s.search('a'), q = s.search('b');
a.reject(new Error('old')); await p; s.dispose(); b.resolve('late'); await q;
assert.deepEqual(seen, []);Related questions
Source: AI & Agents — practice tasks — An exercise written for the study programme, not a confirmed interview task.