循环中的异步方法如何依次执行?

时间:2019-07-10 21:01:38

标签: javascript node.js

我想多次从数据库获取数据。如何设置一个循环以200ms的间隔执行getData()函数。如果其中一个成功,则不会触发其余的。这是异步方法,与此处的问题不同:Asynchronous Process inside a javascript for loop

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

由于它们是异步的,因此最终输出时间间隔将非常接近而不是200ms。在短时间内触发了三个“ setTimeout”。例如0.001s 0.002s 0.003s,输出时间为0.201、0.202、2.203。

getData()返回一个承诺。但只要能正常工作,它就可以正常运行。

3 个答案:

答案 0 :(得分:1)

您可以通过在完成下一个setTimeout之前等待setTimeout完成来完成此操作

我不认为像回调setTimeout那样,回调可以做到这一点,因此您应该将其转换为基于承诺的调用

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();

答案 1 :(得分:0)

不要使用循环。如果失败,请调用函数setTimeout()重新运行。

var i = 0;

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

我假设异步函数getDB()返回一个Promise。

答案 2 :(得分:0)

使用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);
  }
};