How do you cancel a fetch request?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
With AbortController. You create one, pass its signal to fetch, and call abort() when the result is no longer wanted.
const controller = new AbortController();
fetch("/api/search?q=hello", { signal: controller.signal })
.then((r) => r.json())
.catch((err) => {
if (err.name === "AbortError") return; // expected, not a failure
throw err;
});
controller.abort();
Handling AbortError separately matters: a cancellation is a normal outcome, and reporting it as an error fills your logs with noise and can show the user a failure that never happened.
A controller is single-use
Once aborted it stays aborted, so create a new one per request. The usual pattern in a search box is to abort the previous request before starting the next:
let inFlight;
async function search(term) {
inFlight?.abort();
inFlight = new AbortController();
const res = await fetch(`/api/search?q=${term}`, { signal: inFlight.signal });
return res.json();
}
This also fixes out-of-order responses, where a slow earlier request lands after a fast later one and overwrites the correct results.
Beyond fetch
The same signal works with addEventListener, which is a tidy way to remove many listeners at once:
el.addEventListener("click", onClick, { signal: controller.signal });
window.addEventListener("resize", onResize, { signal: controller.signal });
controller.abort(); // removes both
AbortSignal.timeout(5000) gives you a signal that aborts itself, which is the simplest way to add a request timeout. AbortSignal.any([a, b]) combines several.
One limit worth knowing: aborting stops the browser waiting for the response, but the server may already have processed the request. Cancellation is not a rollback.
