首页 > 解决方案 > 从另一个异步函数中调用一个异步函数以并行运行

问题描述

我有一个工作异步函数作为主要代码(async function (){...});,使用来自芦苇联系人的一些输入将它们发布到云中。到目前为止一切都很好。

现在我想添加分析簧片是否打开超过 x 秒的功能。如果是这样,我想做一些额外的事情,但同时还在听其他输入。所以我尝试的是:

var threshold;

async function time(threshold){
  var sec = 0;
  var start = new Date(); //set time stamp
  while (sec < threshold){
      // take actual time
      var akt = new Date();
      // calc difference
      var diff = akt.getTime() - start.getTime();
      // calc secs from mills
      sec = Math.floor(diff / 1000);
  } 
  post threshold data to cloud;
  return "Threshold reached";
}

(async function () {

  reading reed permanent {

    if (reed === 1){
      post data to cloud;
      var call = time(20);
      console.log(call);
    }
  }
})();

我不希望主函数仍然监听新的簧片变化,而time循环应该等待阈值并并行工作。

但是我的代码在继续之前等待达到阈值。我怎样才能并行它们?


Gibors帮助后编辑:

现在我坚持验证簧片是否仍然打开或同时关闭。diff > threshold即使簧片同时关闭,我总是会得到一个,因此时间戳应该是更新的......

var id = [];
if (value['contact'] === 1) {
              var bool = "false";
              id[device['manufacturer']] = new Date();
            } else if(value['contact'] === 0) {
              var bool = "true";
              id[device['manufacturer']] = new Date();
              setTimeout( () => {
                var akt = new Date();
                var diff = akt.getTime() - id[device['manufacturer']].getTime();
                if (diff > threshold) {

                  console.log("now: " + diff + "=" + akt.getTime() + "-" + id[device['manufacturer']].getTime());
                }
              }, threshold);
              /*var call = time (50);
              console.log(call);*/
            }
    ```


标签: javascriptasynchronous

解决方案


首先我会解释你的代码有什么问题,然后我会给你一些我认为是更好和更简单的解决方案:

您的time函数被标记为异步,但实际上它没有做任何异步操作。这实际上意味着当函数“返回”时 - 它实际上返回了一个已解决的承诺。但是 promise 仅在最后创建并立即解决,因此它不能完成异步工作。

我相信这样的事情应该有效:

async function time(threshold){
   return new Promise( (resolve, reject) => {
     var sec = 0;
     var start = new Date(); //set time stamp
     while (sec < threshold){
        // take actual time
        var akt = new Date();
        // calc difference
        var diff = akt.getTime() - start.getTime();
        // calc secs from mills
        sec = Math.floor(diff / 1000);
     } 
     post threshold data to cloud;
     resolve("Threshold reached)";
   }
}

现在这将并行运行,并且call当 promise 被解决时,变量只会得到字符串“达到阈值”——这意味着在您当前的代码中,您将获得的日志类似于Promise<pending>. 要仅在完成后记录(并做其他事情),请.then使用call.

您应该注意的一件事是,您必须以某种方式在reed状态(我并没有真正了解它实际上是什么,但我认为它无关紧要)和承诺状态之间进行同步,因为您想做您的 post-当 20 秒结束并且 reed 仍然打开时的超时代码,所以你必须在你的子句中检查它,或者将它传递给 time 函数,如果在时间用完之前状态发生变化.then,它将拒绝承诺等。reed

现在-对于简单的解决方案:在我看来,使用 setTimeout 函数会更好:

setTimeout() 方法设置一个计时器,一旦计时器到期,该计时器就会执行一个函数或指定的一段代码。

所以你可以简单地做这样的事情:

(async function () {

  reading reed permanent {

    if (reed === 1){
      post data to cloud;
      setTimeout( () => { if(reed still open) {/*do what you want after timeout*/}  }, 20 );
    }
  }
})();

推荐阅读