1

I want to get data from db for several times. How to set a loop to execute getData() function in interval like 200ms. And if one of them success, rest of them won't be triggered. It's asynchronous method, and different from question here: Asynchronous Process inside a javascript for loop

for(var i = 0; i < 3; i++){
setTimeout(getData,200);}

This will end up with the output time interval is very close instead of 200ms, since they are asynchronous. Three "setTimeout" are triggered in a short time. like 0.001s 0.002s 0.003s, the output time is 0.201, 0.202, 2.203.

getData() returns a promise. But it can be normal function as long as it works.

4
  • I would suggest moving away from callbacks and towards the new promise paradigm Commented Jul 10, 2019 at 21:10
  • It would be helpful to know what flavor of async getDB is. Does it return a promise? Take a callback? Commented Jul 10, 2019 at 21:15
  • @MarkMeyer It can be a normal function. I pack it here to return promise, since I need some method after this. Commented Jul 10, 2019 at 21:43
  • Lots of options covered here: How to sequence asynchronous operations. Commented Jul 10, 2019 at 23:35

3 Answers 3

1

You can do this by waiting for the setTimeout to finish before executing the next setTimeout

I don't believe this is possible with callbacks, as is the case with setTimeout, so you should transform it into a promise-based call

const promiseSetTimeout = timeout => new Promise(r => setTimeout(r, timeout));

const waitManyTimes = async () => {
    for(let i = 0; i < 3; i++) {
        await promiseSetTimeout(200);
        // do something here, like getDB 
        console.log(i);
    }
}

waitManyTimes();

Sign up to request clarification or add additional context in comments.

Comments

0

Don't use a loop. Have the function call setTimeout() to run itself again if it fails.

var i = 0;

function callGetDB() {
  getDB().then(db => {
    // use DB
  }).catch(() => {
    if (i++ < 3) {
      setTimeout(callGetDB, 200);
    }
  });
}

I'm assuming the asynchronous function getDB() returns a promise.

4 Comments

What if they can all get the data successfully. Can I get the thing like "as soon as one of them receive the data, rest of them stop". Your code will execute for three times if first one already got the answer, right?
The .catch() is only executed when the promise fails. So it stops when one of them succeeds.
I am using your solution. But I just find that if I successfully get the data in second try and resolve() it, it can't be passed to the next funciton in code like . callGetDb().then(data)=>{}. 'data' will be null
I post specific code here stackoverflow.com/questions/57066813/… . Could you please take a look?
0

Using async/await:

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

let main = async() => {
  for(var i = 0; i < 3; i++) {
    let db = getDB();
    if (db)
      return db;
    await sleep(200);
  }
};

1 Comment

getDB is async right? What are you testing with if (db)? If getDB() returns a promise, which isn't clear in the question, you'll need to await it. If it takes a callback...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.