DEV Community

Discussion on: The dangers of async/await

Collapse
lukaszahradnik profile image
Lukáš Zahradník

Hi,
your usage of Promise.all is wrong. You are using Promise.all to achieve parallel execution, but at the same time you are awaiting all of the passed promises, which leads to sequential execution.

await Promise.all([
    await this.getConfig(),
    await this.getUser(),
    await this.checkRussianContext(query)
])

You should not await promises to achieve parallel execution. So right way would be like this

await Promise.all([
    this.getConfig(),
    this.getUser(),
    this.checkRussianContext(query)
])
Collapse
christopherkade profile image
Christopher Kade Author

Absolutely, thanks for catching my mistake. Must have made it while pasting my notes !

Collapse
nudelx profile image
Alex Nudelman

Absolutely! But there is a problem. If one of those will fail it will break all promise.all() iteration and you will be thrown into the catch. So I if you need/want to run fully async and parallel and get all results (errors and values) regardless of the failures you should use this:

 const promiseAllWithAllErrors = function(mapAsync) {
  return Promise.all(
    mapAsync.map(f =>
      f.then(r => Promise.resolve(r)).catch(e => Promise.resolve(new Error(e)))
    )
  )
}


promiseAllWithAllErrors([
   this.getConfig(),
    this.getUser(),
    this.checkRussianContext(query)
])

let's test it with some timeout function

const fun = function(txt) {
  return new Promise((yes, no) => {
    setTimeout(function() {
      if (txt === '2' || txt === '3') {
        no(txt + ' error')
      } else {
        yes(txt)
      }
    }, 5000)
  })
}

 promiseAllWithAllErrors([
  fun('1'),
  fun('2'),
  fun('3'),
  fun('4')
]).then(console.log)

output:

time node /tmp/t.js 
[ '1', Error: 2 error, Error: 3 error, '4' ]

real    0m5.205s.    ==> only 5 sec , instead of 5*4 and all answers in one array without interuptions  
user    0m0.071s
sys     0m0.044s
Thread Thread
lukaszahradnik profile image
Lukáš Zahradník

Well in that case you would use Promise.allSettled, which is basically what you implemented.

Thread Thread
nudelx profile image
Alex Nudelman • Edited on

yea but it still in implementation progress, kinda experimental.

developer.mozilla.org/en-US/docs/W...