简体   繁体   中英

call an async function out of another async function to run parallel

I have a working async function as main code (async function (){...}); , working with some inputs coming from reed contacts posting them into a cloud. All good so far.

Now I want to add the feature analyzing if a reed is open for more then x seconds. If so, I want to do something additionally but still listening to other inputs while that. So what I try is:

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

I wan't the main function still listeing to new reed changes while the time loop should wait for the threshold and do it's job parallel.

But my code waits for the threshold to be reached before continuing. How can I parallel them?


EDIT after Gibors help:

Now I stuck at the point verifying if the reed is still open or was closed meanwhile. I always get a diff > threshold even if the reed is closed in the meanwhile so that the timestamp should be newer...

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);*/
            }
    ```


First i'll explain what wrong with your code, and then i'll give you something I believe is a better and simpler solution:

Your time function is marked as async, but it actually does nothing asynch-ish. This effectively means that when the function "returns"- it actually returns a resolved promise. But the promise is created only at the end and resolves immediately, so it doesn't do its job to be async.

I believe something like this should work:

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)";
   }
}

Now this will run in parallel, and call variable will only get the string "threshold reached" when promise is resolved- which means in your current code, the log you'll get is something like Promise<pending> . To log only when its done (and do your other stuff), use the .then on the promise held by call .

One thing you should notice tho, is that you'll have to somehow sync between the reed status (which I didn't really get what it actually is but I think its irrelevant) and the promise status, because you want to do your post-timeout code when the 20 sec are over AND reed is still open, so you'll have to check it in your .then clause, or pass it to time function which will reject the promise if the reed status changes before time runs out, etc.

Now- for the simple solution: it seems to me you're way better off using the setTimeout function:

The setTimeout() method sets a timer which executes a function or specified piece of code once the timer expires.

So you can simply do something like this:

(async function () {

  reading reed permanent {

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM