Published on May 19, 2024

Abort Controller: How to cancel requests and use cases

Show me the code

Cancelling requests is possible by using the AbortController Web API.

  1. Cancel a request by passing a signal object to fetch. Abort controller instances exposes signal object to communicate with async operations and an abort() method for cancelling them.

    const url = "https://example.com/suggestions";
    
    // 1. instantiate an abort controller
    const controller = new AbortController();
    
    // 2. build the request, pass signal object from the controller in options
    fetch(url, { method: "POST", signal: controller.signal, body: {} })
      .then((response) => response.json())
      .then((data) => console.log(data))
      .catch((error) => console.error(error));
    
    // 3. to cancel the request
    controller.abort();
    
  2. Cancel a request after a timeout period using AbortSignal which creates a signal object which will (auto) abort after the specified milliseconds.

    fetch(url, { method: "POST", signal: AbortSignal.timeout(600), body: {} })
      .then((response) => response.json())
      .then((data) => console.log(data))
      .catch((error) => console.error(error));
    

Abort signal can also be used to build abortable APIs using promises. Check this example from MDN

Likely you are using a data fetching library such as Query, most do offer an api to cancel requests or accept passing a signal parameter. Check the the docs.

Uses cases

From time-to-time, web apps need to fetch/save data or make other asynchronous requests. Network requests similar to other tasks consumes memory and increases the load on servers handling them. Failing to efficiently manage when and how many requests a web app is making will result in poor performance: increased load time and unresponsive UI.

Unless you are loading thousands of requests on page load most network related issues could be easily avoided by debouncing triggering events. Think of an autocomplete component fetching suggestion from an API as the user types.

The primary use case for programmatically cancelling requests is mostly UX, cases requiring a controlled cancellation: dynamic filters like in product search or booking, media uploads and downloads, page transitions & tab switching when there are still active network requests, auto-save or on form submissions where the user is allowed to continue to interact with the forms.

Think of search on booking apps: the user selects a date range, clicks search. Instead of disabling the search button you could allow the user to modify the search query and click search without waiting for the first request to return but you need do cancel any pending request to avoid corrupting the app state.