Cancelling an Async Promise with AbortController
2 min read
In this post, we will be looking into AbortController
and how can we use it to cancel network requests.
We know that fetch
is a method that sends a network request and returns a promise, but what if we wanted to cancel this ongoing request.
For example, consider this scenario where we want to implement a search functionality that displays results during user input, however user typing speed can vary from one to another and we want to cancel the preceding request. We can do it by minimising the number of server requests using AbortController
.
Syntax
AbortController
is an object (controller object) that allows you to abort one or more requests (async requests) when needed.
signal property which allows setting event listener on the property.
abort() method which will set the signal aborted flag.
So when abort() method is called, it will cancel the DOM request before it has been completed and setting the aborted flag to true.
Usage
In order to cancel a fetch request generally, we need to perform 3 steps:
Create an
AbortController
instance which has a signal property (read-only property)1// creare new object instance of abortContoller2let aborter = new AbortController();Pass the
signal
property as a fetch option for signal1// we get the signal and pass it to the fetch request as param2let signal = aborter.signal; // signal is read only3const url =4"https://api.github.com/search/repositories?q=stars:%3E1+language:javascript&sort=stars&order=desc&type=Repositories";5fetch(url, {6method: "GET",7signal,8})9.then((response) => response.json())10.then((res) => {11aborter = null;12return res;13})14.catch((error) => {15if (error.name === "AbortError") return;16console.log("Error ", error);17});Call abortController’s
abort()
method to cancel all fetches that are pending which use the signal.1aborter.abort();
Example
The following snippet shows how to use abortController with fetch. Here is the full example:
abortController
1let aborter = null;2const getRepos = (lang) => {3// cancel pending request if there is any4if (aborter) aborter.abort();5aborter = new AbortController();6let signal = aborter.signal;7const url = `https://api.github.com/search/repositories?q=stars:%3E1+language:${lang}&sort=stars&order=desc&type=Repositories`;8return fetch(url, {9method: "GET",10signal,11})12.then((response) => response.json())13.then((res) => {14aborter = null;15return res;16})17.catch((error) => {18if (error.name === "AbortError") return;19console.log("Error ", error);20});21};22// the first call will be aborted23getRepos("javascript").then((res) => {24console.log(res);25});26getRepos("python").then((res) => {27console.log(res);28});
The reason we are defining the aborter variable outside the function scope so that regardless of how many times the function is called or how many requests are still pending, it will only display the results of the last request that was submitted.
And here you can see the example above in action with the first call being aborted and the second one going through.
Conclusion
In this post, we looked at AbortController
and how can we use it to cancel network requests with an example usage with fetch.