【问题标题】:How to use Promise.all() after Promises created in for loop在 for 循环中创建 Promise 后如何使用 Promise.all()
【发布时间】:2017-06-30 00:52:13
【问题描述】:

我有一个函数 foo(),它包含一个在 for 循环中解析的 Promise。我想运行 foo() 几次,每次都给它不同的参数。然后我想用所有这些的结果做点什么。 Promise.all() 会在 for 循环结束时运行,还是在 foo() 内的所有 Promise 返回后运行?或者它会说“这些 foo() 都不是 Promise!”还笑我?

var foo = (x) => {
    for (var i = 0; i < 100; i++) {
        someOtherFunctionThatReturnsAPromise(x).then(returnSomething());
    }
};

function nowDoEverything() {
    return Promise.all([foo(1), foo(2), foo(3)]).then(doSomethingWithAllThoseReturnedValues());
}

nowDoEverything();

foo() 是否需要返回一个 Promise?如果是这样,考虑到 foo() 内部的 Promises 是在 for 循环内生成的,我该怎么做?

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all 声明 “Promise.all(iterable) 方法返回一个当可迭代参数中的所有承诺都已解决时解决的承诺,或者以第一个被拒绝的承诺的原因拒绝。”

这个视频https://www.youtube.com/watch?v=RRgAdi3gX-s 非常擅长解释基本的 Promise,但我似乎正在尝试做一些架构师没有打算/期望的事情。

【问题讨论】:

    标签: javascript promise


    【解决方案1】:

    是的,没错。这是Promise.all()的签名:

    Promise.all<T>: (Iterable<Promise<T>): Promise<T[]>
    

    基本上,它接受一个可迭代的 Promise,并返回一个 Promise。

    通过传递foo() 的结果,foo() 应该会返回一个 Promise 本身,否则它将不起作用。

    【讨论】:

    • 嗯,它会立即解析为[undefined, undefined, undefined]
    • @Ryan Right,这根本不是很有帮助。
    【解决方案2】:

    是的,foo() 需要返回一个承诺。您可以将每个 Promise 添加到一个数组中并使用 Promise.all 等待所有这些:

    var foo = x => {
        var results = [];
    
        for (var i = 0; i < 100; i++) {
            results.push(
                someOtherFunctionThatReturnsAPromise(x)
                    .then(returnSomething)
            );
        }
    
        return Promise.all(results);
    };
    

    【讨论】:

      【解决方案3】:

      将 promise 推送到数组,foo 中的 return 数组,在 .then() 内的函数中省略 () 以避免立即调用函数。在 foo() 调用中使用扩展元素将单个承诺数组返回给链接到 Promise.all().then()

      var foo = (x) => {
          var arr = [];
          for (var i = 0; i < 100; i++) {
              arr.push(someOtherFunctionThatReturnsAPromise(x).then(returnSomething));
          }
          return arr
      };
      
      function nowDoEverything() {
          return Promise.all([...foo(1), ...foo(2), ...foo(3)])
                 .then(doSomethingWithAllThoseReturnedValues)
      }
      
      nowDoEverything()
      .catch(err => console.log(err));
      

      【讨论】:

      • 太好了,谢谢!省略号 (...foo(1)) 有什么用?
      • @GlenPierce ... 标点符号可以是扩展元素或休息元素,具体取决于使用情况,请参阅What is SpreadElement in ECMAScript documentation? Is it the same as Spread operator at MDN?。如果没有展开元素,将有三个或 N 次 foo 调用数组,数组从 Promise.all() 传递给 .then(),而不是单个数组。 Promise.all([[1,2,3], [4,5,6]]).then(data =&gt; console.log(data)); Promise.all([...[1,2,3], ...[4,5,6]]).then(data =&gt; console.log(data)).
      猜你喜欢
      • 2018-08-29
      • 2019-01-28
      • 2019-01-07
      • 2020-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 2017-12-09
      相关资源
      最近更新 更多