Reputation: 12434
I am trying to queue a bunch of asynchronous calls to fire in parallel. However, the promises I am queuing have additional data that I want to keep along with the promise value.
My question is: how can I pass an object or array, which contains a promise, and have the promises resolve to a value within the object?
For example, let’s generate a normal array of promises:
async function asyncFunction(input) {
return input * 10;
}
async function main() {
var promises = [];
for (let i = 0; i < 10; i++) {
promises.push(asyncFunction(i));
}
var result = await Promise.all(promises);
document.getElementById('output').innerText = JSON.stringify(result);
}
main();
<div id='output'></div>
This is working just fine. But now if we try to place the promise into an object, with some metadata:
async function asyncFunction(input) {
return input * 10;
}
async function main() {
var promises = [];
for (let i = 0; i < 10; i++) {
promises.push({
id: i,
value: asyncFunction(i)
});
}
var result = await Promise.all(promises);
document.getElementById('output').innerText = JSON.stringify(result);
}
main();
<div id='output'></div>
The value in value
is a promise, and not the resolved value.
My expected output is:
[{"id":0,"value":0},{"id":1,"value":10},{"id":2,"value":20},...]
Upvotes: 1
Views: 41
Reputation: 135217
You could use Array.from
with an async mapping function -
async function asyncFn(input) {
return input * 10;
}
function main() {
return Promise.all(Array.from(
Array(10),
async (_, i) => ({ id: i, value: await asyncFn(i) })
))
}
main().then(console.log, console.error)
.as-console-wrapper { min-height: 100%; top: 0; }
Upvotes: 0
Reputation: 3483
You could map over the array of promises and await the value key containing the promise to resolve
async function asyncFunction(input) {
return input * 10;
}
async function main() {
var promises = [];
for (let i = 0; i < 10; i++) {
promises.push({
id: i,
value: asyncFunction(i)
});
}
var result = await Promise.all(promises.map(async (promise) => ({
id: promise.id,
value: await promise.value
})));
document.getElementById('output').innerText = JSON.stringify(result);
}
main();
Upvotes: 1
Reputation: 224904
You can push promises that resolve to the format you want:
async function asyncFunction(input) {
return input * 10;
}
async function main() {
let promises = [];
for (let i = 0; i < 10; i++) {
promises.push(
asyncFunction(i).then(value => ({
id: i,
value,
}))
);
}
let result = await Promise.all(promises);
console.log(result);
}
main();
Upvotes: 1