skip to Main Content

I want to set a timeout locally if there is no response from the api call, and cancel the call if no response after i.e 10 seconds. How can this be done using settimout method or promise? Example(with mistakes):

const func() = await fetch(api)  // Here `fetch` is used for example, I am asking the question as general fetching operations from db, or firebase
setTimeout(()=>{
    cancelFunc()  // if no response after 10 seconds
},10000)

2

Answers


  1. EDIT: Fetch call needs to be cancelled, Promise.race not suitable method.

    The best way to do this depends a bit on what you are hoping will happen. If all you want is a timeout for a fetch request, you could use [Promise.race][1].

    This function takes an array of promises and returns a new promise that resolves or rejects as soon as one of the promises in the array resolves or rejects.

    const timeout = (ms) => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                reject(new Error("Request timed out"));
            }, ms);
        });
    };
    
    const fetchWithTimeout = async (url, options, timeoutInMs) => {
        return Promise.race([
            fetch(url, options),
            timeout(timeoutInMs)
        ]);
    };
    
    try {
        const response = await fetchWithTimeout(api, {}, 10000);
        // process response
    } catch (error) {
        console.error(error);
        // handle timeout error
    }
    

    But this is just selecting whichever promise ‘wins’ the race. Importantly, it does not cancel the fetch operation.

    If that doesn’t matter to you, then np! But if it does you should consider a different approach, using an AbortController, which is arguably best practice for this type of operation (as mentioned by another commenter)

    [1]: https://www.w3schools.com/jsref/jsref_promise_race.asp

    Login or Signup to reply.
  2. Source

    async function fetchWithTimeout(api) {
        try {
            const response = await fetch(api, {
                signal: AbortSignal.timeout(10000) // timeout
            })
            const data = await response.json()
            return data
        } catch (error) {
            // Timeouts if the request takes
            // longer than 10 seconds
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search