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(1
和 2
)的分辨率作为一个数组,然后创建一个新数组,每个数组乘以 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。当您创建和解决承诺时,您使用resolve
和reject
。当您处理时,如果您的处理失败,您确实会抛出异常来触发失败路径。是的,您也可以从原始的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 实现时执行操作
React Native 为啥我的代码在完成任务之前执行? Promise.all().then() 异步问题