goodstudent404
goodstudent404

Reputation: 33

Set different intervals to call a specific asynchronous function

I would like to call an asynchronous function getDetail() for the next 5s, 10s, 20s, 40s, 80s, 160s, and the last 8 minutes. While at the last 8 minutes, I would like it to redirect to a STATUS page (either success or failure page depends on the response that I got back from the API).

However, I couldn't get them right for the last 8 minutes as it will first fire all the setTimeout with the for loop then once for loop hits i = 7, it will straight redirect the user to the STATUS page.

Anyone can advice on this? How to better achieve what I want?

const pollingSecs = [5, 15, 35, 75, 155, 315, 480]

for (let i = 0; i < pollingSecs.length; i++) {
    const timer = setTimeout(async () => {
      const { success, data } = await getDetail()
      if (success) {
          // // redirect to STATUS page
      }
    }, pollingSecs[i] * 1000)

    if (i === pollingSecs.length - 1) { // at the last 8 minutes
      clearTimeout(timer)
      // redirect to STATUS page
    }
  }

Upvotes: 1

Views: 64

Answers (3)

Nice Books
Nice Books

Reputation: 1861

My answer is based on @gog except it uses Promise.any

var timings = [5, 15, 35, 75, 155, 315, 480].map(n=>n*1000)
var promiseList = timings.map(t=> 
    new Promise((resolve,reject)=> {
        setTimeout(async()=> {
            const { success, data } = await getDetail();
            if(success) {
                resolve(data)
            } else {
                reject(data);
            }
        }, t);
    })
);

Promise.any(promiseList).then((data)=>{ // any 1 is successful
    // Redirect to success page
}).catch((data)=> { // all fail
    // Redirect to failure page 
});
     

Upvotes: 0

ealexandros
ealexandros

Reputation: 139

Maybe try something like this:

const pollingSecs = [5, 15, 35, 75, 155, 315, 480]

for (let i = 0; i < pollingSecs.length; i++) {
  setTimeout(async () => {
    const { success, data } = await getDetail()

    if (success) {
        // // redirect to STATUS page
    }

    if (i === pollingSecs.length - 1) { // at the last 8 minutes
      // redirect to failure page
      // redirect to STATUS page
    }
  }, pollingSecs[i] * 1000)
}

Upvotes: 1

gog
gog

Reputation: 11347

I'd replace setTimeout with a Promise:

let sleep = n => new Promise(r => setTimeout(r, n));

const pollingSecs = [5, 15, 35, 75, 155, 315, 480]

for (let secs of pollingSecs) {
    await sleep(secs * 1000);
    const {success, data} = await getDetail();
    if (success) {
        // success!
        return;
    }
}

// failed!

Upvotes: 1

Related Questions