How to use Promise.all() when I'd like to pass an array variable as an argument

谁说胖子不能爱 提交于 2019-12-11 04:45:19

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/46830699/how-to-use-promise-all-when-id-like-to-pass-an-array-variable-as-an-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!