Let’s say I have two promises: the former resolves in three seconds, while the latter resolves in five. I need to wait for both of these before moving on to the next code block.
Depending on how you structure your promises, you will either have to wait five seconds or eight seconds before moving on.
What is the best way to await multiple promises?
My first instinct in the above scenario was to use to await both promises.
await is such a useful keyword in modern JS, that I tend to throw it places without a second thought:
await promiseOne() // Resolves in three seconds
await promiseTwo() // Resolves in five seconds
This looks neat and clean, but how long will it take to resolve? 8 seconds.
promiseOne. In effect, we’re asking it to twiddle its thumbs for three seconds while we wait on the promise.
Can we reduce that wait time by refactoring?
Call then await
Instead of reaching straight for
await, let’s think this through: we want to start both promises, then wait for their resolution. So let’s change it up:
const promiseOnePromise = promiseOne()
const promiseTwoPromise = promiseOne()
How long will it take this code to resolve? 5 seconds (roughly).
By calling the functions that return promises initially, we are “starting the timer” for both. So the three-second and five-second promises are resolving in tandem.
await after calling the promises, we’ll only wait as long as the slowest promise: five seconds in this case.
This is great, but there is one more solution that might be easier.
Promise object has an
all method that accepts any number of promises and resolves when all have been fulfilled. We just need to pass it an iterable like an array:
await Promise.all([promiseOne(), promiseTwo()])
This functions in a similar manner to the previous “call then await” example but is more succinct. In my tests, it was fractions of a millisecond slower, but your mileage may vary.
You can view a live example of this code on Repl: