user9757842
user9757842

Reputation:

Prevent request to wait more than 10s if api doesn't respond

I saw that if a request has no response, it waits more then 60s. In my case I have nested async loop, managed with callbacks and promise. Each element is a api call. So I want to detect for example if an api don't respond after 10seconds to go ahead.

My code for the api requests :

 return new Promise((resolve, reject) => {
        var  start = moment();
        const req = adapterFor(url).request(options, (resp) => {
        //console.log(`El pr ${options.path}`);
            let data = '';
            resp.on('data', (chunk) => {
                data += chunk;
            });


            resp.on('end', () => {
                try {
                tmpData = JSON.parse(data.trim());
                if(tmpData.length != 0 && tmpData.films.length > 0) {
                    data = tmpData.films.filter(v => {
                        return v.film_o.length > 0
                    })
                    resolve(data);
                }else resolve({"Errore" : url,error:some error',error_type:'some error',duration: ((moment() - start) / 1000)+' s'});
                }catch (e) {
                    resolve({"Errore" : url,'error':'HERE MAYBE',error_type:'?!',duration: ((moment() - start) / 1000)+' s'});
                }
                // console.log(colors.gray("EL: " + tmpData.DS.Scheduling.Events.length.length));
            });

        });

        req.end();
    })

Upvotes: 1

Views: 1057

Answers (2)

evayly
evayly

Reputation: 850

If you can utilize ESnext then you can use Promise.race(). Consider the following example:

Promise.race([
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 5000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(2), 10000))
]).then(res => console.log(res))

You can provide multiple promises in an Array and Promise.race will always choose the fastest and resolve this one. So you can take your promise as one element and a timeout as shown above as the second. This promise will then always resolve after the timeout, or when your api call is done. Whatever is first will be resolved.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race

https://jsfiddle.net/yLv64zr5/

Upvotes: 1

BrTkCa
BrTkCa

Reputation: 4783

One option is to indicate a flag to reject after the time configured. In the example below you can see that the variable reqHasFinished is changed inside the request callback, so in case its keeps false you can reject the request:

return new Promise((resolve, reject) => {
    let start = moment(),
        reqHasFinished = false;
    const req = adapterFor(url).request(options, (resp) => {
        reqHasFinished = true;
        let data = '';
        // resp operations here
    });

    // if after 10 seconds the request has not finished, the promise is rejected.   
    setTimeout(() => {
        if (!reqHasFinished) {
            reject('Go ahead');
        }
    }, 10000)

    req.end();
});

Upvotes: 0

Related Questions