Reputation: 12434
I have two asynchronous functions which create promises. Both functions use the same input i
.
async function1(i) {}
async function2(i) {}
I will be calling these functions multiple times with different values for my input, and I want to make my code as efficient as possible, so I want to queue the promises and have them run in parallel using Promise.all()
.
However, I want to get a single result as my final output, which will be an array of objects like so:
[
{
input: i,
result1: result1,
result2: result2
},
...
]
I have accomplished this in two descrete steps:
async function function1(i) {
return i * i
}
async function function2(i) {
return i * i * i
}
async function main() {
var promises = []
for (let i = 0; i < 10; i++) {
let promise = function1(i)
.then(function(result1) {
return {i:i, result1:result1}
});
promises.push(promise)
}
var final = await Promise.all(promises)
var promises2 = [];
for (let i = 0; i < 10; i++) {
let promise = function2(i)
.then (function(result2) {
final[i]['result2'] = result2;
});
promises2.push(promise);
}
await Promise.all(promises2)
console.log(final)
}
main()
However, I feel like this can be accomplished using a single Promise.all()
. Can you tell me how?
Upvotes: 0
Views: 113
Reputation: 12434
EDIT: 333's answer is correct, not mine. This solution will have 2 batches in the queue.
I think I figured it out:
console.log("start")
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function function1(i) {
await sleep(2000);
return i * i
}
async function function2(i) {
await sleep(2000);
return i * i * i
}
async function main() {
var promises = []
for (let i = 0; i < 10; i++) {
let a = function1(i);
let b = function2(i);
let promise = Promise.all([a,b]).then(
function([resulta,resultb]) {
return {i:i, result1: resulta, result2: resultb}
});
promises.push(promise)
}
var final = await Promise.all(promises)
console.log(final)
}
main()
Note that I added a sleep function to test the parallelization of these functions. Everything runs in 2 seconds, so I think it is optimized.
Upvotes: 0
Reputation: 6981
async function function1(i)
{
return i * i
}
async function function2(i)
{
return i * i * i
}
async function main()
{
const promises = [];
for (let i = 0; i < 10; i++)
promises.push(function1(i), function2(i));
const results = await Promise.all(promises);
const data = [];
for (let i = 0; i < 10; i++)
{
const [result1, result2] = results.slice(i * 2, i * 2 + 2);
data.push({ i, result1, result2 });
}
console.log(data);
}
main();
This should work smoothly and quickly. The functions function1
and function2
return Promise
s if you do not await
them, so pushing them onto the promises
array is self-explanatory.
Then you await Promise.all
, which waits until all 20 promises that were fired off have completed. Finally, the second loop runs through the promises that were returned.
In my code I used destructuring assignments. I assume those are available to you since you are using async functions, which implies that you can use ES2017.
Upvotes: 1