Promise.all().then() 解决?

Posted

技术标签:

【中文标题】Promise.all().then() 解决?【英文标题】:Promise.all().then() resolve? 【发布时间】: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
);

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

【问题讨论】:

【参考方案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)

了解更多:

https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Statements/async_function

【讨论】:

如何将参数传递给流程中的每个单独的承诺? @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.

【讨论】:

以上是关于Promise.all().then() 解决?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Promise.all() 在 Promise 实现时执行操作

.then 的 Promise.all 没有执行

React Native 为啥我的代码在完成任务之前执行? Promise.all().then() 异步问题

.then() 在嵌套的 promise.all 和 fetch 完成之前执行

Promise.all:解析值的顺序

Promise 简介