A type-ahead search fires a request per keystroke, and the responses arrive out of order — so the results for “lap” can overwrite the results for “laptop”.
let controller;
async function search(term) {
if (controller) controller.abort();
controller = new AbortController();
try {
const res = await fetch(`/search?q=${term}`, { signal: controller.signal });
render(await res.json());
} catch (e) {
if (e.name !== 'AbortError') throw e;
}
}
Aborting rejects the promise with an AbortError, which has to be distinguished from a real failure or every cancellation is reported as a bug. The signal can be passed to several fetches to cancel them together, which is the neat part. It does not stop the server doing the work — the request has been sent — so this is about the client’s state rather than about saving anyone’s resources.