【问题标题】:How to use Promise.all() when I'd like to pass an array variable as an argument当我想将数组变量作为参数传递时如何使用 Promise.all()
【发布时间】:2017-10-19 13:10:36
【问题描述】:

我在使用 Promise.all() 时遇到问题。

我想将数组变量作为参数传递给 Promise.all(),如下所示。

const promArr = []
if (condition1) {
  promArr.push(() => prom1(arg1, arg2))
}
if (condition2) {
  promArr.push(() => prom2(arg1, arg2))
}
if (promArr.length > 0) Promise.all(promArr)

但即使条件全部为真,上述内容也不会运行承诺函数(prom1prom2)。 (promArr.length 符合我的预期)

如果我将 Promise 函数直接推送到 promArr,恐怕它们在运行时会被推送到 promArr,而不是 Promise.all(promArr)

在这种情况下如何正确使用 Promise?

【问题讨论】:

  • Promise.all 需要一组承诺,而不是一组承诺返回函数。你为什么要包装它们?
  • 您也可以(并且应该)在空数组上调用Promise.all。不需要if (promArr.length > 0)

标签: javascript es6-promise


【解决方案1】:

使用promArr 变量就可以了。但是(顾名思义),它应该是一个 Promise 数组,而不是一个返回 Promise 的函数数组。

const promArr = []
if (condition1) {
  promArr.push(prom1(arg1, arg2))
}
if (condition2) {
  promArr.push(prom2(arg1, arg2))
}
return Promise.all(promArr)

如果我将 Promise 函数直接推送到 promArr,恐怕它们在运行时会被推送到 promArr,而不是 Promise.all(promArr)

Promise.all 不会运行任何功能,你必须自己做。是的,通过在条件块内立即调用prom1prom2,它们将在条件评估后立即启动,但如果它们是正确异步的并且不干扰以下条件,这不是问题。请注意,它们返回的承诺尚未等待,它们将并行处理。

【讨论】:

  • 我只想使用 Promise.all(promArr).then().catch()。 .then().catch() 在上述情况下有效吗?
  • 是的,就是这样(假设您将任何回调传递给thencatch)。
  • 清除。非常感谢。
【解决方案2】:

根据MDNPromise.all() 返回单个 Promise,当可迭代参数中的所有 promise 都已解决 [...] 时,该 Promise 将解决。

尝试推送 Promise :

promArr.push(new Promise((resolve, reject) => {
    console.log(p1, p2);
}));

如果我使用你的例子,我会得到:

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);

如果我将 promise 函数直接推送到 promArr,恐怕它们会运行 那时他们被推送到 promArr,而不是在 Promise.all(promArr)。

如果你想在 Promise.all 上运行所有函数,你可以这样做:

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()))));

这里,.map 将函数数组转换为一个 promise 数组,然后将其提供给 Promise.all()。

这有点棘手,但它确实有效。

【讨论】:

  • 谢谢回答。我注意到这个问题很重要,promArr 包含 Promise.resolve() 或 Promise.reject(),与 promise 函数何时运行无关。此解决方案适用于 promise 运行且代码更复杂的情况。所以我选择更简单的。无论如何,如果 Promise 函数运行时问题很重要,这仍然是一个很好的解决方案。干得好!
猜你喜欢
  • 2020-04-29
  • 1970-01-01
  • 2018-12-01
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-22
相关资源
最近更新 更多