Link copied!
Streamlining Network Requests: How to Cancel Fetch API Calls in JavaScript Technical Log

TechiesAIE Journal

Streamlining Network Requests: How to Cancel Fetch API Calls in JavaScript

TechiesAIE
TechiesAIE
Lead Developer · TechiesAIE
3 min read 637 words

Based on the sources linked below.

Cover image: Martin Vorel · CC BY-SA 4.0 · License · Image source

The Fetch API in JavaScript provides a modern, promise-based interface for making network requests. While powerful, scenarios often arise where an ongoing request needs to be canceled. This could be due to a user navigating away, a component unmounting, or a more recent request superseding an older one. The AbortController interface offers a standardized way to achieve this, allowing developers to manage the lifecycle of asynchronous operations, including Fetch requests, and prevent unnecessary resource consumption.

How AbortController Enables Request Cancellation

The AbortController is a controller object that allows you to abort one or more web requests as needed. You create a new AbortController instance, and it exposes a read-only signal property, which returns an AbortSignal object. This AbortSignal is then passed to the Fetch API's configuration object as the signal option. When the AbortController's `abort()` method is called, it signals all associated fetch requests to terminate.

When a fetch request is aborted, the promise returned by `fetch()` rejects with an `AbortError` exception. This allows developers to gracefully handle cancellation within their asynchronous code, often using `try...catch` blocks.

Implementing Cancellation with Fetch and AbortController

To make a Fetch API request cancelable, follow these steps:

Step 1: Create an AbortController Instance

First, instantiate a new `AbortController` object. This controller will be responsible for sending the cancellation signal.

```javascript const controller = new AbortController(); ```

Step 2: Attach the Signal to Your Fetch Request

When calling `fetch()`, pass the `controller.signal` as part of the `options` object. This links the fetch request to the controller.

```javascript async function fetchData() { try { const response = await fetch('https://example.org/data', { signal: controller.signal }); if (!response.ok) { throw new Error(`Response status: ${response.status}`); } const data = await response.json(); console.log(data); } catch (error) { if (error.name === 'AbortError') { console.log('Fetch request aborted'); } else { console.error('Error fetching data:', error); } } } ```

Step 3: Call abort() to Cancel the Request

At any point before the fetch request completes, you can call `controller.abort()` to cancel the operation. This will trigger the `AbortError` in the associated fetch promise.

```javascript // To cancel the request later controller.abort(); console.log('Request cancellation initiated.'); ```

Practical Example: User-Initiated Cancellation

Consider a scenario where a user clicks a button to fetch data, but then quickly clicks another button to cancel the ongoing operation.

```javascript const fetchButton = document.querySelector("#fetch"); const cancelButton = document.querySelector("#cancel"); let currentController; fetchButton.addEventListener("click", async () => { if (currentController) { currentController.abort(); // Abort previous request if ongoing } currentController = new AbortController(); const signal = currentController.signal; try { console.log("Starting fetch"); const response = await fetch("https://example.org/get", { signal }); console.log(`Response: ${response.status}`); const data = await response.json(); console.log("Data received:", data); } catch (e) { if (e.name === 'AbortError') { console.error(`Fetch aborted: ${e.message}`); } else { console.error(`Error during fetch: ${e}`); } } }); cancelButton.addEventListener("click", () => { if (currentController) { currentController.abort(); console.log("Canceled fetch"); } }); ```

In this example, `currentController` is used to keep track of the active request. If a new fetch is initiated while another is still pending, the previous one is automatically aborted, preventing redundant operations.

Limitations and Considerations

It's important to understand that `AbortController` signals cancellation to the browser, which then stops listening for the response. However, the server might still process the request on its end, especially for long-running operations. The `AbortController` primarily prevents the client from receiving and processing the response, thereby freeing up client-side resources.

Also, an `AbortError` can occur even after the `fetch()` promise has been fulfilled but before the response body has been read. If `controller.abort()` is called at this stage, any subsequent attempt to read the response body (e.g., `response.json()`, `response.text()`) will reject with an `AbortError`.

The `AbortController` is widely available in modern browsers and Web Workers, providing a robust and standardized mechanism for managing the cancellation of asynchronous operations in JavaScript, leading to more responsive and efficient web applications.

Sources