DEV Community

Discussion on: Why to use async & await instead of the Promise class?

Collapse
 
marceliwac profile image
Marceli-Wac

It's worth mentioning the execution within loops and higher order functions (map() etc.) how that is being handled by async/await and promises. There is a nice way of handling multiple async calls with promises, especially if they all run at the same time:

Promise.all(
  someArray.map(
    element => element.asyncCall()
  )
).then(() => console.log('Done!'))

the above is vastly different to the async/await style loops:

someArray.map(
  async (element) => await element.asyncCall()
)
console.log('Done!')

The latter will execute console.log('Done!'); without waiting for the element.asyncCall() calls.

Collapse
 
mvasigh profile image
Mehdi Vasigh • Edited

The two pieces of code are not equivalent though. In one you are wrapping the array in Promise.all, and in the second you are not. You can do the same thing by awaiting Promise.all using async/await syntax.

All async is, is just syntactic sugar over promises. If your code is not managing promises correctly it doesn't much matter which syntax you are using.

Collapse
 
marceliwac profile image
Marceli-Wac

My point was to show that the behaviour is different. I should have probably said "There is a nice way of handling multiple async calls with Promise.all, especially if they all run at the same time". Hats off for clarifying it though!

Thread Thread
 
mvasigh profile image
Mehdi Vasigh • Edited

I'm sorry, I am not trying to be nitpicky, but the behavior is actually not different at all. In both cases you are mapping an array to an array of Promises, but in one case you've wrapped it in Promise.all. I'm not trying to be hostile but just want to clarify it for others reading because this is a common mistake that JavaScript developers make with Promises.

In both cases you are mapping to an array of Promises, because element.asyncCall returns a Promise. That you are wrapping that in another Promise by making your lambda an async function and awaiting it does nothing other than to just wrap another Promise around it. The behavior is identical, the code is different.

EDIT: for example the non-async/await equivalent to your second example is actually roughly the following:

someArray.map(element => {
  return new Promise((resolve, reject) => element.asyncCall()
    .then(resolve)
    .catch(reject)
  )
})
Thread Thread
 
marceliwac profile image
Marceli-Wac

It's hard to disagree with that. Let me clarify this once again because it seems like I didn't explain what I meant quite clearly in either of those comments.

In my previous experience, especially in the beginning I have struggled to grasp the concept of promises, and using the wrapper syntax of async/await was something that I (incorrectly) settled for, instead of taking my time to study promises. That lead me to believe, that writing the second code (async function with awaited call passed into map) will work in the way identical to that described in the first example. It was the mistake that I have made and couldn't get to the bottom of prior to learning the Promises API and the Promise.all() function.

What I meant to say in my original comment was merely the fact, that awaiting asynchronous calls in async lambda (as passed to the map) does not work the same way as wrapping the array of promises in Promise.all() - hence "different behaviour". Yes, it is the same except for the Promise.all() part, which is what I was trying to illustrate from the start.

I'm sure that the example you just gave will further clarify this for any other readers. Thanks again!