-1

I have an async function and in the middle of the function body I have two awaits before finally some logic and a return. How does this get executed? Does AsyncCall1 finish before AsyncCall2 starts or are they started in parallel? What happens in the interim before they both have results?

pseudo javascript code resembling what I am doing:

const myFunction = async () => {
  // some variable declarations

  await AsyncCall1
  await AsyncCall2

  // some logic 

  return someData;

}
Barry
  • 1,800
  • 2
  • 25
  • 46

2 Answers2

2
 await AsyncCall1;
 console.log("one");
 await AsyncCall2;
 console.log("two");

Is equal to:

 AsyncCall1.then(function(){
   console.log("one");
   AsyncCall2.then(function(){
     console.log("two");
   });
 });

How does this get executed?

One actually cant tell. That depends when the promises are resolved. However one will always be logged before two.

Does AsyncCall1 finish before AsyncCall2 starts or are they started in parallel?

Its impossible to say because you dont start the promising function, you just await the results. If you would do:

 await asyncFunc1();
 await asyncFunc2();

Then asyncFunc2 will only be called (/started) after the first function resolved. However if you do:

  const promise1 = asyncFunc(), promise2 = asyncFunc();

  await promise1;
  await promise2;

Then both promises will be started at nearly the same time, then the code will continue the execution after awaiting both. Note that you should add proper error handling here, e.g. catch errors before awaiting (read on here):

 const promise1 = asyncFunc().catch(e => null);     
 const promise2 = asyncFunc().catch(e => null);

What happens in the interim before they both have results?

The js engine executes something else. When both are finished it jumps back to the position the result was awaited.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • 1
    Notice that [`await promise1; await promise2` is an antipattern](https://stackoverflow.com/questions/46889290/waiting-for-more-than-one-concurrent-await-operation), one should always use `await Promise.all([promise1, promise2])` for that. – Bergi Mar 14 '18 at 16:53
  • @Bergi - quick question on that I saw that if I did `Promise.all` if one got rejected the other would too and I wanted both to execute which is how I ended up with this. – Barry Mar 14 '18 at 16:56
  • @Barry No, both are executed and will always settle independently, regardless of which style you use. The difference is just which rejections you will see and when and whether you get unhandled rejection warnings. – Bergi Mar 14 '18 at 17:00
  • @bergi i would definetly not call it an antipattern. – Jonas Wilms Mar 14 '18 at 17:12
  • @JonasW. Why not? It does look like a sensible pattern at first sight, but it does not work properly. We should warn against using it. – Bergi Mar 14 '18 at 17:19
  • @bergi "it does not work properly" ... I certainly disagree. There are good usecases for it. – Jonas Wilms Mar 14 '18 at 17:29
  • @JonasW. You might want to re-read T.J. Crowders answer to the question I linked. – Bergi Mar 14 '18 at 17:35
  • @bergi for shure one should add rejection handlers when the promise is set up – Jonas Wilms Mar 14 '18 at 17:38
  • @JonasW. You mean like [fire-and-forget with handling rejections](https://stackoverflow.com/a/32385430/1048572), and then later coming back to finally wait for it (not quite forgotten) after all? Well yes, you can do that (though I'd then rather write `const promise = asyncFunction(); promise.catch(handleError); …; await asyncFunction(); …; await promise;`), but that's not what most users have in mind when they use this pattern. Also, in your code you *did not* set up rejection handlers for `promise2 = asyncFunc()` so that's the antipattern! – Bergi Mar 14 '18 at 18:01
0

What happens in the interim before they both have results?

The logic next to those functions will be blocked until they finish their job.

How does this get executed? Does AsyncCall1 finish before AsyncCall2 starts or are they started in parallel?

AsyncCall1 finishes before and they won't be execute in parallel.

Regardless of the time that the function AsyncCall1 takes, the function AsyncCall2 won't be executed until AsyncCall1 ends its job.

function AsyncCall1() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve("AsyncCall1");
    }, 2000);
  });
}

function AsyncCall2() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve("AsyncCall2");
    }, 5);
  });
}


const myFunction = async () => {
  let result = await AsyncCall1();
  console.log(result);
  let result2 = await AsyncCall2();
  console.log(result2);

  return someData;
}

console.log("Waiting 2 secs...")
myFunction();

The await blocks the execution, even if function AsyncCall1 doesn't return a Promise:

The await expression causes async function execution to pause until a Promise is fulfilled, that is resolved or rejected, and to resume execution of the async function after fulfillment. When resumed, the value of the await expression is that of the fulfilled Promise.

If the Promise is rejected, the await expression throws the rejected value.

If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise.

function AsyncCall1() {
  return 5;
}

function AsyncCall2() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve("AsyncCall2");
    }, 5);
  });
}


const myFunction = async () => {
  let result = await AsyncCall1();
  console.log(result);
  let result2 = await AsyncCall2();
  console.log(result2);

  return someData;
}

myFunction();
Ele
  • 33,468
  • 7
  • 37
  • 75