JAVASCRIPT

Cancel Pending Fetch API Requests

Learn how to effectively cancel ongoing Fetch API requests using AbortController, improving performance and preventing race conditions in your web apps.

let currentRequestController = null; // To keep track of the last active controller

async function fetchCancellableData(url) {
    // If there's an ongoing request, cancel it
    if (currentRequestController) {
        currentRequestController.abort();
        console.log('Previous request aborted.');
    }

    currentRequestController = new AbortController();
    const signal = currentRequestController.signal;

    try {
        console.log(`Fetching data from: ${url}`);
        const response = await fetch(url, { signal });

        // Reset the controller after successful completion
        currentRequestController = null;

        if (!response.ok) {
            const errorData = await response.json().catch(() => ({ message: response.statusText }));
            throw new Error(`API Error: ${response.status} - ${errorData.message}`);
        }

        const data = await response.json();
        console.log('Data fetched successfully:', data);
        return data;
    } catch (error) {
        // Check if the error is due to abortion
        if (error.name === 'AbortError') {
            console.warn('Fetch request was aborted.');
        } else {
            console.error('Fetch error:', error);
        }
        // Reset the controller even on error (unless it was an abort initiated by this logic)
        if (error.name !== 'AbortError' || !currentRequestController) {
            currentRequestController = null;
        }
        throw error; // Re-throw to propagate the error
    }
}

// Example Usage:
// const API_URL_1 = 'https://jsonplaceholder.typicode.com/posts/1';
// const API_URL_2 = 'https://jsonplaceholder.typicode.com/posts/2';
// const API_URL_SLOW = 'https://httpbin.org/delay/5'; // A slow endpoint for demonstration

// // Simulate rapid requests, where the first one should be cancelled
// fetchCancellableData(API_URL_SLOW).catch(() => {}); // This will likely be aborted
// setTimeout(() => fetchCancellableData(API_URL_1).then(data => console.log('Final data:', data)).catch(() => {}), 100);
// setTimeout(() => fetchCancellableData(API_URL_2).then(data => console.log('Final data:', data)).catch(() => {}), 200);

// // You can also manually abort if needed (e.g., user navigates away)
// // if (currentRequestController) {
// //     currentRequestController.abort();
// //     currentRequestController = null;
// //     console.log('Manually aborted request.');
// // }
How it works: This snippet demonstrates how to cancel ongoing Fetch API requests using the `AbortController` interface. This is crucial for improving performance and preventing race conditions, especially in scenarios like search bars (where previous requests become stale) or component unmounts (to avoid updating unmounted components). An `AbortController` creates an `AbortSignal` that can be passed to a `fetch` request. When the `abort()` method is called on the controller, the associated `fetch` request is terminated, causing the promise to reject with an `AbortError`. The example includes logic to track and automatically cancel previous requests before initiating a new one, ensuring only the most recent request is processed.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs