Javascript使用promises等待条件成立

时间:2017-08-03 15:52:55

标签: javascript asynchronous async-await electron

我正在努力在我的程序中创建一个简单的等待函数。如果可能的话,我想使用promises和async await。到目前为止我所拥有的:

 function waitForCondition(conditionObj) {
   var start_time = new Date().getTime()

   function checkFlag() {
     if (conditionObj.arg == conditionObj.test) {
       console.log('met');
       return new Promise(resolve => setTimeout(resolve, 1));
     } else if (new Date() > start_time + 3000) {
       console.log('not met, time out');
       return new Promise(resolve => setTimeout(resolve, 1));
     } else {
       window.setTimeout(checkFlag, 1000); 
     }
   }
   checkFlag();
 }

  async function run() {
    console.log('before');
    await waitForCondition({arg: '1', test: '1'})
    console.log('after');
  }
  run();

应每1秒检查一次,最长时间为3秒。控制台应如下所示:

'before'
'met'
'after'

3 个答案:

答案 0 :(得分:4)

你必须return承诺:

function waitForCondition(conditionObj) {
  return new Promise(resolve => {
    var start_time = Date.now();
    function checkFlag() {
      if (conditionObj.arg == conditionObj.test) {
        console.log('met');
        resolve();
      } else if (Date.now() > start_time + 3000) {
        console.log('not met, time out');
        resolve();
      } else {
        window.setTimeout(checkFlag, 1000); 
      }
    }
    checkFlag();
  });
}

async function run() {
  console.log('before');
  await waitForCondition({arg: '1', test: '1'})
  console.log('after');
}
run();

我重构了你的代码。要获取当前时间,请使用Date.now()。你可以在没有超时1毫秒的情况下调用resolve

答案 1 :(得分:1)

我相信你真正想要的是

function waitForCondition(conditionObj) {
  var start_time = new Date().getTime()

  async function checkFlag() {
    if (conditionObj.arg == conditionObj.test) {
      console.log('met');
       // return something?
    } else if (new Date() > start_time + 3000) {
      console.log('not met, time out');
      // throw some error?
    } else {
      await new Promise(resolve => setTimeout(resolve, 1000));
      return checkFlag();
    }
  }
  return checkFlag();
}

或使用循环而不是递归

async function waitForCondition(conditionObj) {
  var start_time = new Date().getTime()

  while (true) {
    if (conditionObj.arg == conditionObj.test) {
      console.log('met');
      break; // or return
    }
    if (new Date() > start_time + 3000) {
      console.log('not met, time out');
      break; // or throw
    }
    await new Promise(resolve => setTimeout(resolve, 1000));
  }
}

答案 2 :(得分:0)

您的函数waitForCondition隐含地返回undefined。尝试在结尾添加一个返回语句:

return checkFlag();

正如评论中提到的那样,checkFlag()返回undefined可能需要处理Promise的一个条件。