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

Syntax for using Promise.all() result to perform another query

我有一个 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一个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 } }
            );
    }

I have a Promise.all() that performs two queries one after the other

那不是 Promise.all 所做的。两个操作 运行 并行,都在你得到 upsertDeviceIdcreateEndpoint 时开始(这可能是你从其他地方得到的承诺),并且 Promise.all 等待它们在履行其承诺之前被履行(或在拒绝其承诺之前等待其中之一拒绝)。

但是假设你确实想 运行 它们并行,你通常做的是 return 第三个查询的结果(不会 运行 直到两个前面的完成):

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' });
    });
});

注意 performThirdQuery 之前的 return。假设 performThirdQuery return 是一个承诺,这会将第一个履行处理程序的承诺解析为 performThirdQuery 的承诺(当您将承诺 解析为 另一个承诺,它使前者的结果由后者的结果决定)。在另一种情况下(upsertDeviceIdResult.upsertedCount > 0 不正确),处理程序只是隐式地 returns undefined。当第一个处理程序的承诺得到履行时,第二个履行处理程序 运行s 立即使用 undefined 或者,当 upsertDeviceIdResult.upsertedCount > 0 true 时诺言实现了。

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