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


95

使用节点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()。我不能resolve(...)先用.then()。我知道我可以做到这一点:

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

但这似乎不是执行此操作的正确方法...正确的方法是什么?

Answers:


142

但这似乎不是正确的方法。

确实,这是正确的做法(或者至少正确的方法)。这是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;
  });

...但是如果它是异步的,您将不想这样做,因为它最终会嵌套,并且嵌套会很快失去控制。


1
有趣。谢谢。那么reject在初始Promise函数之后不可能有一个值吗?还是会在链中的任何地方引发错误,将您带到.catch()?如果是这样,那么reject首先是什么呢?为什么不仅仅抛出错误?再次感谢,
杰克·威尔逊

6
@JakeWilson:这些是不同的问题。但是,您会混淆两件事:创建和解决承诺,以及处理承诺。在创建和履行承诺时,请使用resolvereject。当你处理,如果处理失败,你确实抛出一个异常触发失败路径。是的,您还可以从原始Promise回调中引发异常(而不是使用reject),但并非所有失败都是异常。
TJ Crowder 2015年

1

今天,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)

学到更多:


1
如何将参数传递给流程中的每个单独的承诺?@ Aminadav Glickshtein
bhaRATh

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.