How to cancel a fetch request
Short answer
Create an AbortController, pass its signal to fetch() and call abort() to cancel:
const controller = new AbortController();
fetch('/api/big-file', { signal: controller.signal })
.then((response) => response.blob())
.catch((error) => {
if (error.name === 'AbortError') console.log('Download cancelled');
});
cancelButton.addEventListener('click', () => controller.abort());Only the latest search
When a user types quickly, old answers may come later than new ones. Cancel the previous request before sending the next:
let controller = null;
searchInput.addEventListener('input', async () => {
controller?.abort();
controller = new AbortController();
try {
const response = await fetch(`/api/search?q=${encodeURIComponent(searchInput.value)}`, {
signal: controller.signal,
});
showResults(await response.json());
} catch (error) {
if (error.name !== 'AbortError') throw error;
}
});Common mistake
A controller can be cancelled only once. After abort() its signal stays cancelled, so create a new controller for each request.
const controller = new AbortController();
controller.abort();
console.log(controller.signal.aborted);Output:
trueFunctions used in this recipe
- fetch — Sends an HTTP request and returns a promise of the response.