Explain Codes LogoExplain Codes Logo

Fetch API Request Timeout?

javascript
fetch-api
timeout-handling
async-programming
Anton ShumikhinbyAnton ShumikhinΒ·Feb 7, 2025
⚑TLDR

To manage a timeout in a Fetch API request, integrate fetch with a timeout signal using AbortController. If the request exceeds the expected time, the controller ceases the fetch request.

const fetchTimeout = (url, options, timeout = 3000) => { const controller = new AbortController(); const id = setTimeout(() => controller.abort(), timeout); // Time's up! πŸ•‘ return fetch(url, {...options, signal: controller.signal}) .finally(() => clearTimeout(id)); // Clean up after yourself! 🧹 }; // Use it like this: fetchTimeout('https://api.example.com/data', {}, 5000) .then(response => /* handle response */) .catch(error => /* handle error */);

The finally block ensures the clearing of the timeout, preventing potential resource leaks. The fetch request is aborted if the timeout is exceeded, which triggers the catch block.

Deep dive into Fetch API request timeout

AbortController: Unleashing The Power

AbortController provides vast control beyond mere timeouts. It empowers you with more granular control over multiple fetch calls and can handle newer Web APIs like streams, filesystem, and web bluetooth. NodeJS has integrated AbortController with these operations, bringing the future into the present.

Combat Browser compatibility issues

The ease of AbortSignal.timeout() may be thwarted by browser compatibility issues. Fear not! For those scenarios, a polyfill or a combination of setTimeout and controller.abort() brings the day.

Error handling and Fetch patterns

Meticulously handle the TimeoutError in your catch block. This helps to distinguish network issues and timeouts. Consider employing patterns like fetchWithTimeout.js that make your code reusable and clean.

Custom timeouts in Fetch API

Promise.race: The Fast and The Fetch-ious

By combining the signal property from AbortController with Promise.race, we ensure a neat handling of fetch resolutions and timeouts:

const controller = new AbortController(); const signal = controller.signal; const fetchPromise = fetch('https://api.example.com/data', { signal }); const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000) ); Promise.race([fetchPromise, timeoutPromise]) .then(response => /* handle response */) .catch(error => /* handle error */);

In this code, Promise.race establishes a healthy competition between the fetch request and the timeout promise β€” may the fastest lessor win! πŸƒβ€β™€οΈ

Custom Fetch Timeout Boon

Take a step further by wrapping such strategies in convenient functions like fetchTimeout. This helps in managing the timeout as well as giving provision for manual abort through a signal, thus bestowing your project with a reusable and easy to manage fetch strategy.

Advanced applications of Fetch Timeout

Defaulting timeouts creatively

Adopt default timeouts across all your fetch requests to prevent indefinite waits. Encapsulating this logic within a higher-order function promotes a cleaner codebase and uniformity.

Rejection and Resolution etiquette

Ensure to clear your timeout once the fetch resolves to prevent unnecessary operations. Design a strategy where every fetch invocation respects the set timeout rules. It's just the polite thing to do! πŸ‘

One signal to rule them all

In cases where AbortSignal.timeout is unavailable, use the trusty AbortController along with setTimeout. This ensures that your functions are backward compatible and can boldly face inconsistent browser implementations.

Join the modern Async brigade

Embrace async/await with fetch and timeouts. This leads to cleaner, more readable code and simplifies the jungle of handling promises and errors.