You could have a utility function that used an object instead of an array, something along these lines:
async function allKeyed(promises) {
// Get an array of [name, value] pairs for the object's properties
const entries = Object.entries(promises);
// Wait for any thenables/promises in the values to settle
const values = await Promise.all(entries.map(([_, value]) => value));
// Build an object from those result values; this works because the
// array from `Promise.all` is in the same order as the array of
// values we gave it above.
const result = Object.fromEntries(entries.map(([key], index) => {
return [key, values[index]];
}));
return result;
}
Then it would be something like:
const {a, b, c} = await allKeyed({
a: promise1,
b: promise2,
c: promise3,
});
...but with meaningful names rather than a, b, and c. :-)
Live Example:
async function allKeyed(promises) {
// Get an array of [name, value] pairs for the object's properties
const entries = Object.entries(promises);
// Wait for any thenables/promises in the values to settle
const values = await Promise.all(entries.map(([_, value]) => value));
// Build an object from those result values; this works because the
// array from `Promise.all` is in the same order as the array of
// values we gave it above.
const result = Object.fromEntries(entries.map(([key], index) => {
return [key, values[index]];
}));
return result;
}
function fetchSomething(value) {
return new Promise(resolve => {
setTimeout(() => {
console.log(`fulfilling with ${value}`);
resolve(value);
}, Math.floor(Math.random() * 1000));
});
}
(async () => {
const {a, b, c} = await allKeyed({
a: fetchSomething("ayy"),
b: fetchSomething("bee"),
c: fetchSomething("see"),
});
console.log({a, b, c});
})()
.catch(error => console.error(error));
In the question you were assigning the promises to variables before Promise.all using the same names for both the promises (to feed into Promise.all) and their fulfillment values (in the destructuring), which would look like this:
// ...assign promises to `resultX`, then:
({result1, result2, result3} = await allKeyed({result1, result2, result3}));
I have them in order there, but this would work just as well:
// ...assign promises to `resultX`, then:
({result3, result1, result2} = await allKeyed({result1, result2, result3}));
Live Example:
async function allKeyed(promises) {
// Get an array of [name, value] pairs for the object's properties
const entries = Object.entries(promises);
// Wait for any thenables/promises in the values to settle
const values = await Promise.all(entries.map(([_, value]) => value));
// Build an object from those result values; this works because the
// array from `Promise.all` is in the same order as the array of
// values we gave it above.
const result = Object.fromEntries(entries.map(([key], index) => {
return [key, values[index]];
}));
return result;
}
function fetchSomething(value) {
return new Promise(resolve => {
setTimeout(() => {
console.log(`fulfilling with ${value}`);
resolve(value);
}, Math.floor(Math.random() * 1000));
});
}
(async () => {
let result1 = fetchSomething("one");
let result2 = fetchSomething("two");
let result3 = fetchSomething("three");
({result3, result1, result2} = await allKeyed({result1, result2, result3}));
console.log({result1, result2, result3});
})()
.catch(error => console.error(error));