使用 Promise.all() 结果执行另一个查询的语法

问题描述

我有一个 this,它一个一个地执行两个查询。在 Object.create 的结果中,我想使用第二个查询的结果执行第三个查询

如何创建一个可以在 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 });

解决方法

我有一个 Promise.all() 一个接一个执行两个查询

这不是 Promise.all 所做的。这两个操作并行运行,都在您获得 upsertDeviceIdcreateEndpoint(这可能是您从其他地方获得的承诺)时开始,并且 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 返回一个承诺,这会将来自第一个履行处理程序的承诺解析为来自 performThirdQuery 的承诺(当您将一个承诺解析为另一个承诺时,它使前者的结果由后者的结果决定)。在另一种情况下(upsertDeviceIdResult.upsertedCount > 0 不是真的),处理程序只是隐式返回 undefined。当第一个处理程序的承诺得到履行时,第二个履行处理程序运行,要么立即使用 undefined,要么当 upsertDeviceIdResult.upsertedCount > 0 is 为真时,当该承诺得到履行时。

在现代环境中(包括任何模糊的最新版本的 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]) => {
        // ...