Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why Javascript async/await code run async in parellel

I saw this good article to introduce async/await from Google.

However, I couldn't understand why these code run in parallel

async function parallel() {
  const wait1 = wait(500);
  const wait2 = wait(500);
  await wait1;
  await wait2;
  return "done!";
}

And this run in series

async function series() {
  await wait(500);
  await wait(500);
  return "done!";
}

Why is the key difference between these two methods ? In my opinion, both of them are await promise and should work the same result.

Here is my test code. Can run in browser console which support async/await.

function wait(){
    return new Promise((res)=>{setTimeout(()=>{res()}, 2000)})
}
async function parallel() {
  const wait1 = wait();
  const wait2 = wait();
  await wait1;
  await wait2;
  return "done!";
}
async function series() {
  await wait();
  await wait();
  return "done!";
}
parallel().then(res => console.log("parallel!"))
series().then(res => console.log("series!"))

====== Thanks for the answers.
But I still have some question. Why exact the async/await means? In my knowledge, constructing Promise instance would execute directly. Here is my test code

function wait(){
    return new Promise((res)=>{setTimeout(()=>{console.log("wait!");res();}, 2000)})
}

wait()
//Promise {<pending>}
//wait!

let w = wait()
//undefined
//wait!

let w = await wait()
//wait!
//undefined

async function test(){await wait()}
// undefined
test()
//Promise {<pending>}
//wait!

So why const wait1 = wait(); inside parallel function execute directly?
By the way, should I open another question to ask these question?

like image 520
鄭元傑 Avatar asked Dec 23 '22 08:12

鄭元傑


2 Answers

await doesn't cause the Promise or its setTimeout() to start, which seems to be what you're expecting. The call to wait() alone starts them immediately, whether there's an active await on the promise or not.

await only helps you know when the already on-going operation, tracked through the promise, has completed.

So, the difference is just due to when wait() is being called and starting each timeout:

  • parallel() calls wait() back-to-back as quickly as the engine can get from one to the next, before either are awaited, so the 2 timeouts begin/end at nearly the same time.

  • series() forces the 2nd wait() to not be called until after the 1st has completed, by having an await act in between them.


Regarding your edit, async and await are syntactic sugar. Using them, the engine will modify your function at runtime, inserting additional code needed to interact with the promises.

A (possible, but not precise) equivalent of series() without await and async might be:

function series() {
  return Promise.resolve()
    .then(function () { return wait(500) })
    .then(function () { return wait(500) })
    .then(function () { return "done!"; });
}

And for parallel():

function parallel() {
  const wait1 = wait(500);
  const wait2 = wait(500);

  return Promise.resolve()
    .then(wait1)
    .then(wait2)
    .then(function () { return "done!"; });
}
like image 81
Jonathan Lonowski Avatar answered Dec 29 '22 06:12

Jonathan Lonowski


In parallel(), you call both methods and then await their results while in series() you await the result of the first wait() call before calling the second wait().

Why exact the async/await means? In my knowledge, constructing Promise instance would execute directly.

The Promise instance is returned immediately, i.e. synchronously. But the value of the Promise is evaluated asynchronously by calling the first parameter given to its constructor, a function usually called resolve. This is what you are awaiting for.

like image 23
xehpuk Avatar answered Dec 29 '22 06:12

xehpuk