2

I want to suspend execution of a statement if it takes more than certain time. Help me please to achieve this?

In the below given sample snippet of code, if the statement const result = await curly.get('www.google.com'); takes more than 2 seconds of time to complete execution I want to suspend execution of the statement and throw an exception.

const { curly } = require('node-libcurl');

exports.curlFetch = async () => {
  try {
    const result = await curly.get('www.google.com');

    return result;
  } catch (err) {
    console.error('----------ERRORR OCCURRED----------', err);
    throw err;
  }
}
Madhava Reddy
  • 303
  • 2
  • 11
  • 1
    Does this answer your question? [What is the best general practice to timeout a function in promise](https://stackoverflow.com/questions/30936824/what-is-the-best-general-practice-to-timeout-a-function-in-promise) – Rashomon Dec 07 '20 at 14:18

3 Answers3

2

You can use Promise.race()

I have defined an timeout function that returns an promise that rejects after an certain amount of time. If the request is faster then the 3 seconds the result will be resolved otherwise the timeout rejects and you land into the catch block

const { curly } = require('node-libcurl');

exports.curlFetch = async () => {
  try {
    const request = curly.get('www.google.com');
    const result = await Promise.race([request, timeout(3000)])
  
    return result;
  } catch (err) {
    console.error('----------ERRORR OCCURRED----------', err);
    throw err;
  }
}


function timeout(ms) {
   return new Promise((res, rej) => setTimeout(rej("Request took too long"), ms));
}
bill.gates
  • 14,145
  • 3
  • 19
  • 47
2

from msdn

The Promise.race() method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise.

const fetchWithTimeout =  (url, options, timeout = 2000) => {
    return Promise.race([
        fetch(url, options),
        new Promise((_, reject) =>
            setTimeout(() => reject(new Error('timeout')), timeout)
        )
    ]);
}


await fetchWithTimeout('www.google.com',{})

further reading :

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

Naor Tedgi
  • 5,204
  • 3
  • 21
  • 48
0

As the others have suggested, Promise.race() will continue script execution after a timeout, but it will not stop the execution of your curly function. Verify this with:

const wait = (t)=>new Promise((r,j)=> {
  setTimeout(()=>r(t),t*1000)
}); 
Promise.race([ 
  wait(1).then(console.log),
  wait(5).then(console.log)
])

Supposing curly has an abort function on the request you can do:

const TIMEOUT_SEC = 20;
const wait = (t)=>new Promise((r,j)=> {
  setTimeout(()=>r(t),t*1000);
});
let req = curlyWhatever();
let handled = false;
await Promise.race([
  req.then(()=>handled=true),
  wait(TIMEOUT_SEC).then(()=>{
    if(handled)
      return;
    req.abort();
    // do whatever else
  })
])
leitning
  • 1,081
  • 1
  • 6
  • 10