Published time: 2020-07-29

Can you point out the problem with this code?

async function getPeople() {
  const members = await fetch("/members");
  const nonMembers = await fetch("/non-members");

  return members.concat(nonMembers);
}
Copy the code

Take a moment to look at it. Such code may exist in many JS code. Even people who think they know a lot about it make this mistake, including me, which is why I’m writing this article.

As a hint, the code looks like this when async/await is not used:

function getPeople() {
  return fetch("/members")
    .then(members= > fetch("/non-members")
      .then(nonMembers= > members.concat(nonMembers)))
}
Copy the code

Normally we would not write above code because without async/await it is very difficult to make this mistake.

The request log in the browser’s Network panel looks like this

We created two separate asynchronous tasks and put them into a sequence. The getPeople function executes twice as long as it needs to.

The correct code would look like this:

async function getPeople() {
  const members = fetch("/members");
  const nonMembers = fetch("/non-members");
  const both = await Promise.all([ members, nonMembers ]);

  return both[0].concat(both[1]);
}
Copy the code

Do not use aysnc/await:

function getPeople() {
  const members = fetch("/members");
  const nonMembers = fetch("/non-members");

  return Promise.all([ members, nonMembers ])
          .then(both= > both[0].concat(both[1]));
}
Copy the code

At this point the browser requests the log:

Async /await execution instructions

async function foo() {
  const result1 = await new Promise((resolve) = > setTimeout(() = > resolve('1')))
  console.log(result1)
  const result2 = await new Promise((resolve) = > setTimeout(() = > resolve('2')))
  console.log(result2)
}
foo()
console.log(3)
// Output order: 3, 1, 2
Copy the code
  1. The first line of the foo function will be executed synchronously and await the end of the promise. It then suspends the process that passes through Foo and gives control back to the function that called foo.
  2. After a while, when the first promise ends, control reverts back to foo. The example will return 1 (promise state is fulfilled) as the result to the left of the await expression (result1). The function will then continue, reaching the second await area, at which point the process of foo will be suspended again.
  3. Some time later, when the second Promise ends, result2 will be assigned a value of 2, after which the function will execute synchronously and will return undefined by default.

Easy mistake to make

Even if you understand the Promise code that the async/await syntax eventually translates into, it’s easy to fall into this trap. Let alone if you don’t know what promises and async/await are really doing.

Async /await cannot be said to be “bad” (or “harmful”). Especially in languages that don’t have a reasonable API like Promise, or that have other limitations in closures that make promises less easy to use, async/await can make code more readable overall.

But they also have a pretty big catch: They allow us to take asynchronous things and pretend they’re synchronous. The await keyword blocks subsequent code until the promise completes, as if a synchronization operation had been performed. It does allow other tasks to continue running in the meantime, but the code after await is blocked.

This means that the code may be slow due to lots of await promises happening one after another. Each await will wait for the previous one to finish, and what you really want is for all promises to start processing at the same time (just like when we are not using async/await).

General async/await goes wrong in a subtle way that may never be noticed: it only affects performance, not correctness.

Ease the problem

  1. If you’re not sure how your code works, look at your browser’s request waterfall and see if you can speed up your application.

  2. You can also use this rule of thumb: if an await function is not calling the result (or getting stuff from the result) with another await function, you should use promise.all () to make them execute synchronously.

The original link

  • Beware of Async/Await | Brandon’s Website
  • Async and await: let the asynchronous programming more simple – | MDN learning Web development