node.js - 使用 Promise.all() 结果执行另一个查询的语法
问题描述
我有一个一个Promise.all()
接一个地执行两个查询。在Promise.all()
我想使用第二个查询的结果执行第三个查询的结果中。
我将如何创建一个function()
我可以在里面干净地使用的Promise()
?
Promise
.all([upsertDeviceId, createEndpoint])
.then((values) => {
const upsertDeviceIdResult = values[0];
const createEndpoint = values[1];
if(upsertDeviceIdResult.upsertedCount > 0){
//Perform third query here
//performThirdQuery(createEndpoint.EndpointArn);
}
return res.status(200).send({ success: true });
})
.catch((err) => {
console.log(err);
return res.status(400).send({ reason: 'unknown' });
});
});
我想不通的是如何收听第三个查询的结果并返回一个return res.status(200).send({ success: true });
或错误。
return res.status(500).send({ success: false});
function performThirdQuery(resultFromSecondQuery) {
const updateDeviceIdEndpointArn = db.collection('deviceids')
.updateOne(
{ device_id: deviceId },
{ $set: { device_endpoint_arn: deviceId } }
);
}
解决方案
我有一个一个
Promise.all()
接一个地执行两个查询
那不是这样Promise.all
做的。这两个操作并行运行,都在你得到upsertDeviceId
and时开始createEndpoint
(这可能是你从其他地方得到的承诺),并Promise.all
在履行其承诺之前等待它们都被履行(或等待其中一个在拒绝之前拒绝它承诺)。
但是假设您确实想并行运行它们,您通常做的是返回第三个查询的结果(在前两个查询完成之前不会运行):
Promise
.all([upsertDeviceId, createEndpoint])
.then((values) => {
const upsertDeviceIdResult = values[0];
const createEndpoint = values[1];
if(upsertDeviceIdResult.upsertedCount > 0){
return performThirdQuery(createEndpoint.EndpointArn);
}
})
.then(() => {
res.status(200).send({ success: true });
})
.catch((err) => {
console.log(err);
res.status(400).send({ reason: 'unknown' });
});
});
注意return
之前的performThirdQuery
. 假设performThirdQuery
返回一个promise,这会将promise 从第一个履行处理程序解析为promise from performThirdQuery
(当您将promise 解析为另一个promise 时,它使前者的结果由后者的结果决定)。在另一种情况下(upsertDeviceIdResult.upsertedCount > 0
不正确),处理程序只是隐式返回undefined
。第二个履行处理程序在第一个处理程序的承诺被履行时运行,或者立即执行,undefined
或者当upsertDeviceIdResult.upsertedCount > 0
为真时,当该承诺被履行时。
在现代环境中(包括最近的 Node.js 版本),您可以使用async
函数await
来代替:
// (In an `async` function)
const [upsertDeviceIdResult, createEndpoint] = await Promise.all([upsertDeviceId, createEndpoint]);
try {
if (upsertDeviceIdResult.upsertedCount > 0) {
await performThirdQuery(createEndpoint.EndpointArn);
}
res.status(200).send({ success: true });
} catch (err) {
console.log(err);
res.status(400).send({ reason: 'unknown' });
}
旁注——而不是:
.then((values) => {
const upsertDeviceIdResult = values[0];
const createEndpoint = values[1];
// ...
您可以在参数列表中使用解构:
.then(([upsertDeviceIdResult, createEndpoint]) => {
// ...
推荐阅读
- javascript - 存储在单个数组中的从 1 到 10 的所有数字的 Collatz 序列
- r - 尝试从数据框中删除所有非数字列
- wpf - wpf 在 LiveCharts 列中指定不透明度
- javascript - 如何使用云页面更新 Salesforce 对象中的多条记录
- javascript - 带有javascript的烛台图
- reactjs - Next.js 路由:动态与精确
- excel - 打开csv文件时禁用excel将字符串转换为日期
- julia - 运行 Julia 代码时未显示 ProfileView 绘图
- java - 如何使用 Java 从 z/OS 读取 VSAM 文件?
- mysql - 如何对mysql表中的多个列进行连接