Ignore stale async results
Requests do not come back in the order they were sent. A search for 'a' can answer after a search for 'ab', overwriting the results with older ones — a race condition users see as the list flickering back to the wrong thing.
Implement latestOnly(fn). It returns a wrapped function that calls fn on every invocation, passing its arguments through, and returns a promise. Only the most recent invocation may settle with fn's outcome. The moment a newer invocation starts, every earlier invocation whose promise is still pending rejects with new Error("Superseded"). When an outdated call's underlying promise finally settles, that result is discarded — and an outdated rejection must not surface as an unhandled rejection. Calls made after the previous one has already settled behave completely normally.
Arguments
fn(...args: any[]) => Promise<T>- The underlying async function to wrap.
Returns
Function — A wrapped function. Only the most recent invocation's promise settles with fn's outcome; superseded invocations reject with Error("Superseded").
Examples
const search = latestOnly((query, ms) =>
new Promise((resolve) => setTimeout(() => resolve("results:" + query), ms))
);
const stale = search("a", 40).catch((e) => "no:" + e.message);
const fresh = search("ab", 5);
// await stale === "no:Superseded"
// await fresh === "results:ab"Older in-flight calls reject the moment a newer one starts.
What it has to do
- Call
fnon every invocation, with the arguments passed through. - Reject a superseded pending call with an
ErrorreadingSuperseded. - Settle the newest call with
fn's own result, whenever it arrives. - Discard the outcome of outdated calls, including their rejections.
- Behave normally for calls made after the previous one settled.
Notes
- Track an incrementing token per call and ignore any settlement whose token is no longer the latest — simpler than real cancellation.
- Catch outdated rejections so they don't surface as unhandled promise rejections in the console.
Stuck? The javascript course covers everything this challenge needs.
- 1.a slow earlier call cannot beat the newest one
- 2.only the last of three overlapping calls survives
- 3.sequential calls both resolve normally
- 4.the wrapped function still runs for every call
- 5.an outdated rejection is discarded quietly
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.