AJAX - AJAX Request Cancellation Using AbortController

Modern web applications often send multiple requests to the server as users interact with the interface. For example, while typing in a search box, every keystroke may trigger an AJAX request. If the user types quickly, several requests may be sent before earlier ones have finished. These unnecessary requests consume network bandwidth, increase server load, and may even cause outdated data to appear on the screen. To solve this problem, modern JavaScript provides the AbortController API, which allows developers to cancel an ongoing AJAX request before it completes.

What is AbortController?

AbortController is a built-in JavaScript API introduced to give developers control over asynchronous operations, especially Fetch API requests. It allows a running request to be terminated whenever it is no longer needed.

Before AbortController was introduced, developers often had difficulty stopping AJAX requests. Once a request was sent using the Fetch API, it continued until completion. With AbortController, developers can cancel unwanted requests, resulting in faster applications and a better user experience.

The AbortController consists of two main parts:

  • AbortController Object: Responsible for controlling the request.

  • AbortSignal Object: Passed to the Fetch API to monitor whether the request should be canceled.

Why Request Cancellation is Important

There are many situations where canceling an AJAX request is beneficial:

  • The user starts typing a new search query before the previous request finishes.

  • A user leaves the current page before data loading completes.

  • Multiple button clicks trigger duplicate requests.

  • Slow internet connections delay server responses.

  • Applications need to prevent unnecessary API usage.

Without request cancellation, outdated responses may overwrite newer information, confusing users and reducing application performance.

How AbortController Works

The request cancellation process follows these steps:

  1. Create an AbortController object.

  2. Obtain its signal property.

  3. Pass the signal to the Fetch API request.

  4. If cancellation becomes necessary, call the abort() method.

  5. The Fetch request immediately stops and throws an AbortError exception.

This mechanism allows developers to control when a request should continue or terminate.

Basic Syntax

const controller = new AbortController();

fetch("https://api.example.com/data", {
    signal: controller.signal
});

controller.abort();

In this example:

  • A controller object is created.

  • The signal property is attached to the Fetch request.

  • Calling abort() immediately cancels the request.

Example: Canceling a Search Request

const controller = new AbortController();

fetch("https://api.example.com/search?query=laptop", {
    signal: controller.signal
})
.then(response => response.json())
.then(data => {
    console.log(data);
})
.catch(error => {
    if (error.name === "AbortError") {
        console.log("Request cancelled");
    } else {
        console.log(error);
    }
});

setTimeout(() => {
    controller.abort();
}, 2000);

Explanation

  • The request begins immediately.

  • A timer waits for two seconds.

  • If the request has not finished within two seconds, abort() is called.

  • The Fetch API throws an AbortError.

  • The catch block identifies the cancellation and handles it separately from other errors.

Using AbortController in Live Search

One of the most common applications of AbortController is live search.

Suppose a user types:

C
Co
Cod
Coda
Codag
Kodagu

Without cancellation:

  • Six AJAX requests are sent.

  • Earlier responses may arrive after later ones.

  • Older search results may replace the latest results.

With AbortController:

  • Every new keystroke cancels the previous request.

  • Only the latest request reaches completion.

  • Users always see results for the most recent input.

Example:

let controller;

function search(keyword) {

    if (controller) {
        controller.abort();
    }

    controller = new AbortController();

    fetch(`https://api.example.com/search?q=${keyword}`, {
        signal: controller.signal
    })
    .then(response => response.json())
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        if (error.name !== "AbortError") {
            console.log(error);
        }
    });
}

Here, every new search automatically cancels the previous one before sending a fresh request.

Canceling Multiple Requests

Sometimes several requests need to be canceled together.

Example:

const controller = new AbortController();

fetch("users.json", {
    signal: controller.signal
});

fetch("products.json", {
    signal: controller.signal
});

fetch("orders.json", {
    signal: controller.signal
});

controller.abort();

All three requests stop immediately because they share the same AbortController.

Handling Abort Errors

When a request is canceled, Fetch throws an exception.

Example:

.catch(error => {

    if (error.name === "AbortError") {
        console.log("Request was cancelled.");
    }
    else {
        console.log("Unexpected error");
    }

});

Checking for "AbortError" ensures that request cancellations are not treated as actual application failures.

Using AbortController with Async/Await

AbortController also works with async functions.

Example:

async function loadData() {

    const controller = new AbortController();

    try {

        const response = await fetch("data.json", {
            signal: controller.signal
        });

        const data = await response.json();

        console.log(data);

    }
    catch(error){

        if(error.name === "AbortError"){
            console.log("Cancelled");
        }

    }

}

The behavior remains the same whether using promises or async/await.

Advantages of AbortController

  • Reduces unnecessary network traffic.

  • Improves application responsiveness.

  • Prevents outdated server responses from displaying.

  • Saves server resources.

  • Enhances the user experience during rapid interactions.

  • Simplifies request management in modern JavaScript applications.

  • Works seamlessly with the Fetch API.

  • Provides cleaner and more maintainable code.

Limitations

  • AbortController is designed for the Fetch API and may not work directly with older XMLHttpRequest-based code.

  • Canceling a request does not guarantee that the server stops processing it; it only stops the browser from waiting for the response.

  • Older browsers may require polyfills if AbortController support is unavailable.

Best Practices

  • Always create a new AbortController for each independent request.

  • Cancel previous requests in search suggestions and autocomplete features.

  • Handle AbortError separately from genuine network or server errors.

  • Avoid sharing one controller across unrelated requests unless all should be canceled together.

  • Use request cancellation in applications that frequently send AJAX requests, such as dashboards, chat systems, search engines, and filtering interfaces.

Real-World Applications

AbortController is widely used in modern web applications, including:

  • Live search and autocomplete systems.

  • E-commerce product filtering.

  • Social media news feeds.

  • Online maps and location searches.

  • Weather applications with frequently updated data.

  • Stock market dashboards.

  • Online booking and reservation systems.

  • Real-time analytics platforms.

  • Single Page Applications (SPAs).

  • Progressive Web Applications (PWAs).

Conclusion

AbortController is an essential feature for managing modern AJAX requests. By allowing developers to cancel unnecessary or outdated requests, it improves application performance, reduces network overhead, and ensures users always receive the most relevant information. When combined with the Fetch API, AbortController provides a simple and efficient way to build responsive, reliable, and user-friendly web applications.