I'm in a problem using Promise.all().
I'd like to pass an array variable as an argument to Promise.all() like below.
const promArr = []
if (condition1) {
promArr.push(() => prom1(arg1, arg2))
}
if (condition2) {
promArr.push(() => prom2(arg1, arg2))
}
if (promArr.length > 0) Promise.all(promArr)
But above doesn't run the promise functions(prom1
, prom2
) even if conditions are all true. (promArr.length
is as I expected)
if I push promise functions directly to promArr
, I'm afraid they run at that time they are pushed to promArr
, not at Promise.all(promArr)
.
How can I use Promise properly in this case?
Using a promArr
variable is just fine. However (as the name suggests), it should be an array of promises, not an array of functions that return promises.
const promArr = []
if (condition1) {
promArr.push(prom1(arg1, arg2))
}
if (condition2) {
promArr.push(prom2(arg1, arg2))
}
return Promise.all(promArr)
if I push promise functions directly to promArr
, I'm afraid they run at that time they are pushed to promArr
, not at Promise.all(promArr)
.
Promise.all
won't run any functions, you have to do it yourself. Yes, by calling prom1
and prom2
immediately inside the conditional block, they will start right after the condition is evaluated, but if they're properly asynchronous and don't interfere with the following conditions that is not a problem. Notice that the promises they return are not awaited yet, they'll do their processing in parallel.
According to the MDN, Promise.all()
returns a single Promise that resolves when all of the promises in the iterable argument have resolved [...].
Try to push Promises :
promArr.push(new Promise((resolve, reject) => {
console.log(p1, p2);
}));
If I use your example, I get :
const p1 = 1;
const p2 = 2;
const promArr = [];
if (condition1)
promArr.push(new Promise((resolve, reject) => {
console.log(p1, p2);
}));
if (condition2)
promArr.push(new Promise((resolve, reject) => {
console.log(p1, p2);
}));
Promise.all(promArr);
if I push promise functions directly to promArr, I'm afraid they run
at that time they are pushed to promArr, not at Promise.all(promArr).
If you want to run all functions at Promise.all, you can do something like that :
const p1 = 1;
const p2 = 2;
const promArr = [];
if (condition1)
promArr.push(() => prom1(arg1, arg2));
if (condition2)
promArr.push(() => prom1(arg1, arg2));
Promise.all(promArr.map((prom) => new Promise((resolve) => resolve(prom()))));
Here, the .map
transform the array of function into an array of promises who is given to the Promise.all().
That's a bit tricky but it's working.