Harnessing Control: Exploring JavaScript’s AbortSignal Timeout and Any Methods

Netanel Basal
Netanel Basal
Published in
3 min readApr 20, 2024

--

In web development, managing asynchronous operations, such as fetching data or downloading files, often involves handling situations where operations need to be aborted. The AbortSignal interface, introduced in the DOM in modern web browsers, provides a way to abort asynchronous operations gracefully.

In this article, we'll delve into two lesser-known static methods of AbortSignal: AbortSignal.timeout() and AbortSignal.any(). These methods offer powerful capabilities for managing and responding to asynchronous tasks effectively. They are fully supported by all major web browsers.

AbortSignal Timeout

The AbortSignal.timeout() static method offers a convenient way to create an AbortSignal that automatically aborts after a specified duration. This method returns an AbortSignal instance that aborts with a TimeoutError DOMException if the specified time elapses before the operation completes.

Additionally, it aborts with an AbortError DOMException if the user initiates a stop action, such as pressing the browser's stop button.

const fetchFile = async (url, timeout) => {
try {
const response = await fetch(url, {
signal: AbortSignal.timeout(timeout) 👈👈👈
});
const file = await response.blob();
// Process the file
console.log("File fetched successfully:", file);
} catch (error) {
handleFetchError(error);
}
};

const handleFetchError = (error) => {
switch (error.name) {
case "TimeoutError":
console.error("The operation timed out.");
break;
case "AbortError":
console.error("The fetch operation was aborted.");
break;
default:
console.error(`An error occurred: ${error.message}`);
}
};

// Example usage
const fileUrl = "https://path_to_large_file.mp4";
const fetchTimeout = 5_000; // 5 seconds

fetchFile(fileUrl, fetchTimeout);

This example demonstrates using AbortSignal.timeout() to fetch a file within a timeout limit of 5 seconds. Depending on the outcome, it distinguishes between timeout errors, user-initiated aborts, and other potential errors.

AbortSignal Any

The AbortSignal.any() static method enables combining multiple AbortSignal instances into one, facilitating coordinated abort actions. It accepts an iterable of abort signals and returns an AbortSignal that aborts whenever any of the input signals are aborted. The abort reason corresponds to the first signal that triggers the abortion.

const cancelDownloadBtn = document.querySelector('button');
const userCancelController = new AbortController();

cancelDownloadBtn.addEventListener("click", () => {
userCancelController.abort();
});

const timeoutDuration = 1_000 * 60 * 5; // 5 minutes

// Create a combined signal to handle cancellation and timeout
const timeoutSignal = AbortSignal.timeout(timeoutDuration);
const combinedSignal = AbortSignal.any([
userCancelController.signal,
timeoutSignal,
]);

try {
const response = await fetch(someUrlToDownload, {
signal: combinedSignal 👈👈👈
});
const downloadedContent = await response.blob();
// Process downloaded content
} catch (error) {
if (error.name === "AbortError") {
// Handle cancellation
} else if (error.name === "TimeoutError") {
// Handle timeout
} else {
// Handle other errors (e.g., network error)
}
}

In this example, AbortSignal.any() is employed to create a combined signal that aborts either when the user cancels the download or when the timeout duration of 5 minutes is reached, whichever occurs first.

We can also use it with any API that accepts AbortSignal, for example:

document.querySelector('button').addEventListener(
'click',
() => { },
{
// Cancel the event after 4 seconds
signal: AbortSignal.timeout(4_000),
}
);

Follow me on Medium or Twitter to read more about Angular and JS!

--

--

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.