What is AbortController?
TheÂ
AbortController
 interface represents a controller object that allows you to abort one or more Web requests as and when desired.You can create a newÂ
AbortController
 object using the AbortController()
 constructor. Communicating with a DOM request is done using an AbortSignal
 object.Why do we need to use AbortController?
For example, when users want to search for something on our web application.
The request will be like this:
- Request 1 (R1):
/search?q=kon
- Request 2 (R2):
/search?q=konvoy
- Request 3 (R3):
/search?q=konvoy+kegs
In the normal network, we expect responses to be returned in order. That means the R1 will complete first. Then comes R2 and R3.
But how about if there’s a problem from server, it makes R3 complete first, then R2, R1?
Take a look at the code below:
const [data, setData] = useState([]); setTimeout(async () => { try { if (keyword) { setLoading(true); const response = await searchSomething( { keyword: keyword, }, id ); setData(items); setLoading(false); } } catch (err) { console.error(err) } }, 300)
In case the R3 completed first, then R2, R1. The data will contain the result of R1, not R3. We surely don’t want it happen.
That why we will use
AbortController
How to use AbortController?
Read the sample code below
class ApiOption { ... abort?: { key?: string; enabled?: boolean; }; } class ApiClient { private requests: Record<string, AbortController>; private async request( method: HttpMethods, endpoint: string, options?: ApiOption ) { // sample request key should be: GET/locations/search[order-form-w] const requestKey = `${method}${path}[${key || ''}]`; // check if abort flag is enabled or not if (enabled) { const previousRequest = this.requests[requestKey]; if (previousRequest) { // call this function to abort the previous request previousRequest.abort(); } } // init new AbortController const abortController = new AbortController(); // we will get the signal from AbortController instance const { signal } = abortController; this.requests[requestKey] = abortController; await fetch(endpoint, { signal: signal, ... }); ... } public async searchSomething() { return this.request('GET', '/xxx/...', { abort: { enabled: true } }); } }
Â
Use Case
In most cases, we need to combine debounce input and AbortController together.
Follow the example below. You’ll see:
- When the user typing
kon
→ because we already applied to debounce input → onlykon
is sent to our server.
- The user continues typing → the 2nd request with
konvoy
keyword has been called → because we already applied AbortController ⇒ the 1st request has been canceled
Using this way, we do not need to be concerned about the data. Only the latest data will be responded