Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is `await` resolved simultaneously?

The MDN documentation for async function currently gives the following combined example of two ways to use await. I've reordered it just a bit for emphasis:

function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}


async function add1(x) {
  const a = await resolveAfter2Seconds(20);
  const b = await resolveAfter2Seconds(30);
  return x + a + b;
}

async function add2(x) {
  const p_a = resolveAfter2Seconds(20);
  const p_b = resolveAfter2Seconds(30);
  return x + await p_a + await p_b;
}


add1(10).then(v => {
  console.log(v);  // prints 60 after 4 seconds.
});

add2(10).then(v => {
  console.log(v);  // prints 60 after 2 seconds.
});

This was a bit surprising to me. Why does

const a = await resolveAfter2Seconds(20);
const b = await resolveAfter2Seconds(30);
return x + a + b;

resolve the two promises sequentially, while

return x + await p_a + await p_b;

seemingly resolves the two promises simultaneously? Is this behavior specified for await specifically, or a natural consequence of something else?

like image 417
natevw Avatar asked Oct 31 '17 23:10

natevw


People also ask

Do I need the promise resolve() prologue with async/await?

Here the answer is: you no longer need the Promise.resolve () prologue with async/await. async functions implicitly catch synchronous exceptions and return a rejected promise instead, guaranteeing singular error handling and a promise return value: await doSomething(""()); // bug!

What is “async/await”?

There’s a special syntax to work with promises in a more comfortable fashion, called “async/await”. It’s surprisingly easy to understand and use. Let’s start with the async keyword. It can be placed before a function, like this: The word “async” before a function means one simple thing: a function always returns a promise.

How does the await function work in JavaScript?

If this await is the last expression executed by its function, execution continues by returning to the function's caller a pending Promise for completion of the await 's function and resuming execution of that caller. If a Promise is passed to an await expression, it waits for the Promise to be fulfilled and returns the fulfilled value.

How does await work with non promises?

If await gets a non-promise object with .then, it calls that method providing the built-in functions resolve and reject as arguments (just as it does for a regular Promise executor). Then await waits until one of them is called (in the example above it happens in the line (*)) and then proceeds with the result.


1 Answers

async function add2(x) {
  const p_a = resolveAfter2Seconds(20);
  const p_b = resolveAfter2Seconds(30);
  return x + await p_a + await p_b;
}

In this statement p_a and p_b are started in parallel (i.e., as soon as you generate the promise), so when you await p_a and p_b they would appear parallel, not sequential.

To get the other functionality (await in series) you would need to:

return x + await resolveAfter2Seconds(20) + await resolveAfter2Seconds(30);
like image 177
Cody G Avatar answered Oct 07 '22 17:10

Cody G