async await promise all versus storing in a variable

Viewed 339

I was looking at the MDN documentation for async await and found that there is an alternative to promise.all

so,

if coffee , tea and description are three promises we can await them all

let values = await Promise.all([coffee, tea, description]);

But the MDN also gives example of slow and fast async await:

Example of slow async await:

async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

Example of fast async await:

async function timeTest() {
  const timeoutPromise1 = timeoutPromise(3000);
  const timeoutPromise2 = timeoutPromise(3000);
  const timeoutPromise3 = timeoutPromise(3000);

  await timeoutPromise1;
  await timeoutPromise2;
  await timeoutPromise3;
}

I am confused about fast async await. Does it work similar to promise.all()? Is it better than promise.all()?

If we are writing multitple awaits in different lines how is it any different from slow async await?

1 Answers

This snippet:

async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

will initialize each Promise only after the last has completed.

  • Initialize first Promise
  • Wait for it to finish (3 seconds)
  • Initialize second Promise (...etc)

In contrast, this snippet:

async function timeTest() {
  const timeoutPromise1 = timeoutPromise(3000);
  const timeoutPromise2 = timeoutPromise(3000);
  const timeoutPromise3 = timeoutPromise(3000);

  await timeoutPromise1;
  await timeoutPromise2;
  await timeoutPromise3;
}

will initialize all promises at once. Then, it'll

  • wait for the first Promise to resolve
  • wait for the second Promise to resolve
  • wait for the third Promise to resolve

But the second snippet has a serious deficiency: if one of the promises happens to reject, it may result in an unhandled rejection despite there being an await before it. This could happen if, for example, timeoutPromise1 has not resolved yet, and timeoutPromise2 rejects:

window.addEventListener('unhandledrejection', () => {
  console.error('Unhandled rejection :(');
});

async function timeTest() {
  const timeoutPromise1 = new Promise(resolve => setTimeout(resolve, 5000));
  const timeoutPromise2 = new Promise((resolve, reject) => setTimeout(reject, 500));
  
  await timeoutPromise1;
  await timeoutPromise2;
}

timeTest()
  .catch((error) => {
    console.log('Error caught');
  });

This problem occurs because a Promise must be being awaited or have a .catch chained onto it at the point at which it rejects. If it rejects before a .catch or await is connected to it, an unhandled rejection will result.

Unhandled rejections, just like unhandled errors, are ugly and should be avoided. In Node, unhandled rejections aren't just bad, they're also deprecated, and can crash the Node process entirely.

So, using Promise.all is a better approach than your second snippet.

Related