0

I'm working with an API that requires info requests to be made one at a time. If there's multiple requests, I'd like to make an attempt to get them all, but it's an all or nothing situation. If we don't get them all after 2 seconds, move to the next step without them.

I know this is possible using promises, but I keep getting the behavior to either way for them, or forcibly wait 2 seconds, even if it has them all after 1.

Any advice or guidance would be greatly welcome.

Also, it adds the info to a store, so it would be best the api call running in the background to get that info regardless of if the next stage got access to it.

  • Payload comes in with key array
  • I begin a recursive function to ping API for keys one at a time
  • If not all keys are back after 2 seconds, continue the payload to the next step
  • Continue the key storing process even if it passes 2 seconds
  • If are back early, do not wait for the full 2 seconds

Thanks in advance, truly appreciate any help or implementation suggestions.

  • 2
    *I know this is possible using promises, but I keep getting the behavior to either way for them* - what did you try? – Estus Flask Aug 17 '18 at 18:04
  • to be clear, I'm not very experienced with them. I used an implementation I found at: https://ourcodeworld.com/articles/read/317/how-to-check-if-a-javascript-promise-has-been-fulfilled-rejected-or-resolved but couldn't get it fully functioning. If you have any guide that could easily achieve the same I'd gladly try, but I'm having trouble finding anything myself.. – Dev for Fun Aug 17 '18 at 18:12

3 Answers3

4

This looks like a good opportunity to use Promise.race. Something on the lines of:

const bomb = new Promise((resolve, reject) => setTimeout(reject, 2000));
const data = await Promise.race([bomb, fetch(request)]);
Sid Vishnoi
  • 1,250
  • 1
  • 16
  • 27
1

You can create a fetch request wrapped with a promise. Implementation details will vary, however the basic implementation will work like this:

const promise = new Promise((resolve, reject)=>{
  setTimeout(reject, 2000, 'foo');
  fetch(request).then(resolve).catch(reject);
});

For more information go here:

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

EDIT: Looking at your quesiton again, I saw that you said you are using Node. This means that you won't want a timeout hanging around in the background. This will happen with Promise.race() or my implementation. Here is a fix to remove the timeout so that your server won't be bogged down with many requests creating and holding timeouts:

const promise = new Promise((resolve, reject)=>{
  timeout = setTimeout(reject, 2000, 'foo');
  fetch(request)
       .then((res)=>{

       resolve(res);
       clearTimeout(timeout);

    }).catch(reject);
});
David Kamer
  • 2,677
  • 2
  • 19
  • 29
  • Note that this works because JavaScript does not pause. More information here: https://stackoverflow.com/questions/10258012/does-javascript-settimeout-stop-other-script-execution – David Kamer Aug 22 '18 at 19:37
0
//Either ms gets resolved or rejected in ms
const promiseTimeout = function(ms, promise){

    // Create a promise that rejects in <ms> milliseconds
    let timeout = new Promise((resolve, reject) => {
      let id = setTimeout(() => {
        reject('Timed out in '+ ms + 'ms.')
      }, ms)
    })

    // Returns a race between our timeout and the passed in promise
    return Promise.race([
      promise,
      timeout
    ])
  }


var resolvedPromisesArray = [Promise.resolve(call1), Promise.resolve(call2)];

var p = Promise.all(resolvedPromisesArray);

console.log(promiseTimeout(2000,p));

Have a look at the above piece. Either both call 1 and call2 get resolved or the function waits for 2 secs and times out issuing a reject. To learn more promises, use MDN or check out https://italonascimento.github.io/applying-a-timeout-to-your-promises/

Ashutosh
  • 1,000
  • 15
  • 39
  • Why would you clear the timeout inside of the timeout's callback? That callback only executes after the timeout you are clearing is already "cleared". Basically it wouldn't even do anything. – David Kamer Aug 22 '18 at 20:20