What is AbortController : Managing and Cancelling API Requests
Imagine an e-commerce website where a user searches for a product such as “laptop.” As the user types, the website sends API requests to fetch matching products.
"lap" → Request 1
"laptop" → Request 2
"laptop hp" → Request 3
If the user types quickly, multiple requests may run at the same time. An older request could finish after the latest request and return outdated results.
So, how can JavaScript cancel an API request that is no longer needed?
This is where AbortController can help. It allows developers to cancel ongoing fetch() requests and manage asynchronous operations more efficiently.
Using AbortController with Fetch
AbortController can be used with the fetch() API to cancel an ongoing request. The controller's signal is passed to fetch(), and calling abort() cancels the request.
const controller = new AbortController();
fetch("/api/products", {
signal: controller.signal
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.log(error);
});
// Cancel the request
controller.abort();
Explanation of Code
- Here, controller.signal connects the fetch() request with the AbortController. When controller.abort() is called, the request is cancelled.
- If the request is cancelled, the catch() block receives an AbortError. In a real application, we can handle this separately so that an intentionally cancelled request is not treated as a normal error.
- This approach is useful when a user changes their search before the previous API request has finished. The application can cancel the old request and process only the latest search.
Real-World E-Commerce Example
Consider an e-commerce website with a product search feature. When a user searches for a product, the application sends a request to the server.
If the user changes the search query before the previous request finishes, the previous request is no longer useful. We can cancel it using AbortController.
let controller;
async function searchProducts(query) {
if (controller) {
controller.abort();
}
controller = new AbortController();
try {
const response = await fetch(
`/api/products?q=${query}`,
{
signal: controller.signal
}
);
const products = await response.json();
console.log(products);
} catch (error) {
if (error.name === "AbortError") {
console.log("Previous request cancelled");
} else {
console.error("Request failed:", error);
}
}
}
How it works
When the user enters a new search query, the application first checks whether a previous request is running. If it is, controller.abort() cancels that request.
A new AbortController is then created for the latest request. This ensures that the application focuses on the most recent search instead of processing unnecessary older requests.
For example:
- User searches "laptop" → Request 1 starts → User searches "laptop HP" → Request cancelled → Request 2 starts → Latest results displayed
- This improves request management and helps prevent outdated search results from being displayed to the user.
Real-World Use Cases
AbortController is useful whenever an application sends asynchronous requests that may become unnecessary. Some common use cases are:
-
E-commerce search: Cancel the previous product-search request when the user enters a new query.
-
Autocomplete: Stop an old suggestion request when the user continues typing.
-
Dynamic filtering: Cancel previous API requests when users quickly change filters.
-
Live dashboards: Cancel outdated requests when the user changes the selected data or time period.
-
Search Autocomplete: Cancel previous requests when users continue typing to fetch the latest search suggestions.
-
Maps: Cancel previous location or search requests when the user changes their location or search query.
These use cases help applications avoid unnecessary work and ensure that users receive the most relevant and recent results.
Limitations
Although AbortController is useful, it has some limitations:
- It does not automatically prevent a request from being sent; the request must be connected to its signal.
- Cancelling a client-side fetch() does not guarantee that server-side processing has been completely stopped.
- Developers need to handle AbortError properly to avoid showing unnecessary error messages.
- AbortController only solves request cancellation; techniques such as debouncing may still be needed to reduce how frequently requests are created.
Benefits
- Better Performance: Reduces unnecessary API requests and network usage.
- Faster User Experience: Helps display only the latest and relevant results.
- Prevents Outdated Results: Avoids older requests from updating the UI.
- Reduces Server Load: Cancelling unnecessary requests can reduce the amount of work handled by the application.
- Better Resource Management: Helps efficiently manage asynchronous operations in web applications.
Error Handling
API requests can fail for different reasons, so proper error handling is important in real-world applications.
Common cases include:
- 200 → Request successful
- 404 → Resource not found
- 500 → Server error
- Network failure → Request could not be completed
-
AbortError → Request was intentionally cancelled