Stop Wasting API Calls: How to Cancel Pending Requests Like a Pro

Vaibhav Tyagi
calendar_month
February 13, 2025
timer
3 min
read time

In modern web applications, handling multiple asynchronous requests efficiently is crucial for optimal performance. However, when users navigate away, switch tabs, or trigger multiple actions rapidly, pending API requests can continue running in the background, wasting resources and causing performance issues.

In this article, you'll be learning how to solve this common problem using request cancellation.

The Challenge: Uncontrolled Pending Requests

At Shorter Loop, we encountered a significant challenge in our document tool. Every keystroke triggered an API request for data retrieval. This meant that a typical user typing 100-200 characters per minute generated an equal number of API calls, leading to several critical issues:

Impact

1. Performance Degradation:

The high volume of concurrent API calls significantly slowed down the application.

2. API Rate Limit Exceedance:

The frequency of requests quickly exceeded our API rate limits.

3. Data Inconsistency:

Older requests completing after newer ones could override more recent data.

4. Poor User Experience:

The combination of these issues resulted in a suboptimal user experience.

The Solution: Implementing AbortController

JavaScript's AbortController provides an elegant solution for canceling in-progress requests when they're no longer needed. This native API allows developers to maintain control over pending requests and cancel them when appropriate.

How AbortController Works

The AbortController creates an abort signal that can be passed to fetch or XMLHttpRequest calls. You can cancel any request at any time after initiation by calling the `.abort()` method on the AbortController instance.

Implementation Example

function getData() {
    // Cancel any existing request
    if (currentController) {
        currentController.abort();
    }

    // Create new controller for this request
    currentController = new AbortController();
    const signal = currentController.signal;

    fetch('https://api.example.com/data', { signal })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                console.log(data);
                currentController = null;
            }
        })
        .catch(error => {
            if (error.name === 'AbortError') {
                console.log('Request was aborted');
            } else {
                console.error('Other error:', error);
            }
        });
}

Benefits of Request Cancellation

1. Resource Optimization:

Prevents unnecessary API calls from consuming server resources.

2. Improved Performance:

Reduces the number of concurrent requests, leading to better application performance

3. Better User Experience:

Ensures users receive the most recent data without delays

4. API Rate Limit Management:

Helps stay within API rate limits by canceling unnecessary requests

Best Practices

- Always maintain a reference to the current AbortController instance
- Cancel existing requests before making new ones for the same resource
- Handle abort errors appropriately in your error handling logic
- Clean up controller references after successful requests or component unmounting

Conclusion

Implementing request cancellation using AbortController is a powerful way to optimize your application's performance and provide a better user experience. By managing pending requests effectively, you can prevent resource waste and ensure your application runs smoothly even under heavy user interaction.