How do you abort a web request using `AbortController` in JavaScript?
TL;DR
AbortController
is used to cancel ongoing asynchronous operations like fetch requests.
const controller = new AbortController();const signal = controller.signal;fetch('https://jsonplaceholder.typicode.com/todos/1', { signal }).then((response) => {// Handle response}).catch((error) => {if (error.name === 'AbortError') {console.log('Request aborted');} else {console.error('Error:', error);}});// Call abort() to abort the requestcontroller.abort();
Aborting web requests is useful for:
- Canceling requests based on user actions.
- Prioritizing the latest requests in scenarios with multiple simultaneous requests.
- Canceling requests that are no longer needed, e.g. after the user has navigated away from the page.
AbortController
s
AbortController
allows graceful cancelation of ongoing asynchronous operations like fetch requests. It offers a mechanism to signal to the underlying network layer that the request is no longer required, preventing unnecessary resource consumption and improving user experience.
Using AbortController
s
Using AbortController
s involve the following steps:
- Create an
AbortController
instance: Initialize anAbortController
instance, which creates a signal that can be used to abort requests. - Pass the signal to the request: Pass the signal to the request, typically through the
signal
property in the request options. - Abort the request: Call the
abort()
method on theAbortController
instance to cancel the ongoing request.
Here is an example of how to use AbortController
s with the fetch()
API:
const controller = new AbortController();const signal = controller.signal;fetch('https://jsonplaceholder.typicode.com/todos/1', { signal }).then((response) => {// Handle response}).catch((error) => {if (error.name === 'AbortError') {console.log('Request aborted');} else {console.error('Error:', error);}});// Call abort() to abort the requestcontroller.abort();
Use cases
Canceling a fetch()
request on a user action
Cancel requests that take too long or are no longer relevant due to user interactions (e.g., user cancels uploading of a huge file).
// HTML:// <div>// <button id="cancel-button">Cancel upload</button>// </div>const controller = new AbortController();const signal = controller.signal;fetch('https://jsonplaceholder.typicode.com/todos/1', { signal }).then((response) => {// Handle successful response}).catch((error) => {if (error.name === 'AbortError') {console.log('Request canceled');} else {console.error('Network or other error:', error);}});document.getElementById('cancel-button').addEventListener('click', () => {controller.abort();});
When you click the "Cancel upload" button, in-flight request will be aborted.
Prioritizing latest requests in a race condition
In scenarios where multiple requests are initiated for the same data, use AbortController
to prioritize the latest request and abort earlier ones.
let latestController = null; // Keeps track of the latest controllerfunction fetchData(url) {if (latestController) {latestController.abort(); // Abort any previous request}const controller = new AbortController();latestController = controller;const signal = controller.signal;fetch(url, { signal }).then((response) => {// Handle successful response}).catch((error) => {if (error.name === 'AbortError') {console.log('Request canceled');} else {console.error('Network or other error:', error);}});}
In this example, when the fetchData()
function is called multiple times triggering multiple fetch requests, AbortController
s will cancel all the previous requests except the latest request. This is common in scenarios like type-ahead search or infinite scrolling, where new requests are triggered frequently.
Canceling requests that are no longer needed
In situations where the user has navigated away from the page, aborting the request can prevent unnecessary operations (e.g. success callback handling), and freeing up resources by lowering the likelihood of memory leaks.
Notes
AbortController
s is notfetch()
-specific, it can be used to abort other asynchronous tasks as well.- A singular
AbortContoller
instance can be reused or multiple async tasks and cancel all of them at once. - Calling
abort()
onAbortController
s does not send any notification or signal to the server. The server is unaware of the cancelation and will continue processing the request until it completes or times out.