【问题标题】:Syntax for using Promise.all() result to perform another query使用 Promise.all() 结果执行另一个查询的语法
【发布时间】:2021-05-07 22:54:27
【问题描述】:

我有一个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 所做的。

标签: node.js express promise promise.all


【解决方案1】:

我有一个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 返回一个promise,这会将第一个履行处理程序的promise 解析为performThirdQuery 的promise(当您将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]) => {
        // ...

【讨论】:

  • 感谢您的指正。而且哇,非常感谢这个非常全面的答案:)
  • @DIRTYDAVE - :-) 编码愉快!
猜你喜欢
  • 2010-10-31
  • 1970-01-01
  • 2018-10-17
  • 2018-09-12
  • 2018-04-29
  • 2017-11-14
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
相关资源
最近更新 更多