【问题标题】:Promise.all().then() resolve?Promise.all().then() 解决?
【发布时间】:2016-01-09 11:35:04
【问题描述】:

使用节点 4.x。当您有 Promise.all(promises).then() 时,解析数据并将其传递给下一个 .then() 的正确方法是什么?

我想做这样的事情:

Promise.all(promises).then(function(data){
  // Do something with the data here
}).then(function(data){
  // Do more stuff here
});

但我不确定如何将数据发送到第二个.then()。我不能在第一个.then() 中使用resolve(...)。我发现我可以做到这一点:

return Promise.all(promises).then(function(data){
  // Do something with the data here
  return data;
}).then(function(data){
  // Do more stuff here
});

但这似乎不是正确的方法……正确的方法是什么?

【问题讨论】:

    标签: javascript node.js promise


    【解决方案1】:

    但这似乎不是正确的做法..

    这确实是正确的方法(或至少 a 正确的方法)。这是 Promise 的一个关键方面,它们是一个管道,数据可以由管道中的各种处理程序进行处理。

    例子:

    const promises = [
      new Promise(resolve => setTimeout(resolve, 0, 1)),
      new Promise(resolve => setTimeout(resolve, 0, 2))
    ];
    Promise.all(promises)
      .then(data => {
        console.log("First handler", data);
        return data.map(entry => entry * 10);
      })
      .then(data => {
        console.log("Second handler", data);
      });

    (为简洁起见,省略了catch 处理程序。在生产代码中,始终要么传播承诺,要么处理拒绝。)

    我们从中看到的输出是:

    第一个处理程序 [1,2] 第二个处理程序 [10,20]

    ...因为第一个处理程序将两个 Promise(12)的分辨率作为一个数组,然后创建一个新数组,每个数组乘以 10 并返回它。第二个处理程序获取第一个处理程序返回的内容。

    如果你正在做的额外工作是同步的,你也可以把它放在第一个处理程序中:

    例子:

    const promises = [
      new Promise(resolve => setTimeout(resolve, 0, 1)),
      new Promise(resolve => setTimeout(resolve, 0, 2))
    ];
    Promise.all(promises)
      .then(data => {
        console.log("Initial data", data);
        data = data.map(entry => entry * 10);
        console.log("Updated data", data);
        return data;
      });

    ...但如果它是异步的,你不会想要这样做,因为它最终会被嵌套,并且嵌套很快就会失控。

    【讨论】:

    • 有趣。谢谢你。那么在初始的Promise 函数之后是不是不可能reject 一个值?还是会在链中的任何地方抛出错误将您带到.catch()?如果是这样的话,首先reject 有什么意义?为什么不直接抛出错误?再次感谢,
    • @JakeWilson:这些是不同的问题。但是你混淆了两个不同的事情:创建和解决promise,以及handlingpromise。当您创建和解决承诺时,您使用resolvereject。当您处理时,如果您的处理失败,您确实会抛出异常来触发失败路径。是的,您也可以从原始的Promise 回调中抛出异常(而不是使用reject),但并非所有失败都是异常。
    【解决方案2】:

    今天 NodeJS 支持新的async/await 语法。这是一个简单的语法,让生活更轻松

    async function process(promises) { // must be an async function
        let x = await Promise.all(promises);  // now x will be an array
        x = x.map( tmp => tmp * 10);              // proccessing the data.
    }
    
    const promises = [
       new Promise(resolve => setTimeout(resolve, 0, 1)),
       new Promise(resolve => setTimeout(resolve, 0, 2))
    ];
    
    process(promises)
    

    了解更多:

    【讨论】:

    • 如何将参数传递给流程中的每个单独的承诺? @Aminadav Glickshtein
    【解决方案3】:

    您的return data 方法是正确的,这是promise chaining 的一个示例。如果您从 .then() 回调返回一个承诺,JavaScript 将解析该承诺并将数据传递给下一个 then() 回调。

    请小心并确保您使用.catch() 处理错误。 Promise.all() rejects as soon as one of the promises in the array rejects.

    【讨论】:

      猜你喜欢
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 2018-10-11
      • 1970-01-01
      • 2015-02-10
      • 2019-03-11
      • 2020-06-23
      相关资源
      最近更新 更多