How to use Promise.all correctly?

Viewed 5536

Consider the following code:

var result1;
var result1Promise = getSomeValueAsync().then(x => result1 = x);

var result2;
var result2Promise = getSomeValueAsync().then(x => result2 = x);

await Promise.all([result1Promise, result2Promise]);

// Are result1 and result2 guaranteed to have been set at this point?

console.log(result1 + result2); // Will this always work? Or could result1 and/or result2 be undefined because then() has not been executed yet?

When I use the then() method, is it guaranteed to have been executed in-order? E.g. then() will not execute immediately after Promise.all has been resolved?

It seems to work ok in Chrome, but what I'm really looking for is a guarantee that it will always work accroding to some spec?

I'd rather not use Promise.all(...).then(some callback) because then I'm back to using callbacks again...

3 Answers

You can directly use the return value of Promise.all:

const p1 = getSomeValueAsync();
const p2 = getSomeValueAsync();

const [result1, result2] = await Promise.all([p1, p2]);

console.log(result1 + result2);

The Promise.all will only resolve once all promises in its array have resolved. Because your two Promises have .thens of:

.then(x => result1 = x);
.then(x => result2 = x);

The Promise.all will resolve once both of these functions have completed. So yes, both result1 and result2 are guaranteed to be defined (or, at least, to have been assigned to) when the Promise.all callback runs.

Still, rather than assigning to outer variables, it might make more sense to define the variables with const while awaiting the Promise.all:

const [result1, result2] = await Promise.all([getSomeValueAsync(), getSomeValueAsync()]);

Yes they are set. Resolving result1Promise and result2Promise includes setting the result1 and result2 because the promise itself is only fully resolved when .then() is executed.

But if you wand to avoid callbacks at all you should structure your code like this:

const result1Promise = getSomeValueAsync();
const result2Promise = getSomeValueAsync();

const results = await Promise.all([result1Promise, result2Promise]);

console.log(results[0] + results[1]);

Related