简体   繁体   English

如何将我的猫鼬 PROMISE 链交易迁移到 ASYNC / AWAIT 流?

[英]How to migrate my mongoose PROMISE chain transactions to ASYNC / AWAIT flow?

I created an API that integrate database responses in a promise flow, but I think the interpretation of the code is complex and I believe that async / await approach could improve both understanding and the code itself.我创建了一个将数据库响应集成到承诺流中的 API,但我认为代码的解释很复杂,我相信 async/await 方法可以提高理解和代码本身。

The API is built in NodeJS using mongoose 5.6.1 and express 4.17.1.该 API 使用 mongoose 5.6.1 和 express 4.17.1 在 NodeJS 中构建。

Can you help me in improve this?你能帮我改进吗?

Below is the API that I want to improve:以下是我想要改进的 API:

/** New employee */
router.post('/', (req, res) => {
    let { idCompany, name, departament } = req.body;
    let _id = mongoose.Types.ObjectId(); // Generating new MongoDB _ID
    let employeeCreated;

    const promise1 = new Promise((resolve, reject) => {
        // Querying by document '$oid'
        Companies.findOne({ _id: idCompany }, (err, company) => {
            // Error returned
            if (err) reject({ error: "Invalid request, something went wrong!" });
            // Invalid data received
            if (!company) reject({ error: "Unauthorized action!" });
            // Everything OK
            resolve(company);

        });
    })
    .then(company => {
        if(company) {
            const promise2 = new Promise((resolve, reject) => {
                Employees.create({ _id, idCompany, name, departament }, (err, employee) => {
                    // Error returned
                    if (err) reject({ error: "Invalid request, something went wrong!", err });
                    // Everything OK
                    employeeCreated = employee;
                    resolve(company);
                });
            })
            return promise2;
        }else reject({ error: "Company not found!" });
    })
    .then(company => {
        let { name: companyName, address, email, tel, employees } = company;
        employees.push(_id);

        const promise3 = new Promise((resolve, reject) => {
            Companies.findByIdAndUpdate(
                { _id: idCompany },
                { $set: { _id: idCompany, name: companyName, address, email, tel, employees } }, // spotlight
                { new: true },
                (err, company) => {
                    // Something wrong happens
                    if (err) reject({ success: false, error: "Can't update company!" });
                    // Everything OK
                    resolve(company);
                }
            );
        });
        return promise3;
    });

    promise1
        .then(() => res.json({ success: true, employeeCreated }))
        .catch(err =>   res.status(400).json({ error: "Invalid request, something went wrong!", err }));
});

Regards.问候。

One key to using promises with mongoose, is using the exec method:在 mongoose 中使用 promise 的一个关键是使用exec方法:

Your code could then look something like this (not tested):您的代码可能看起来像这样(未经测试):

router.post('/', async (req, res) => {
    try {
        const { idCompany, name, departament } = req.body;
        const _id = mongoose.Types.ObjectId();
        const company = await Companies.findOne({ _id: idCompany }).exec();
        const employeeCreated = await Employees.create({ _id, idCompany, name, departament });
        const { name: companyName, address, email, tel, employees } = company;
        employees.push(_id);
        await Companies.findByIdAndUpdate(
                    { _id: idCompany },
                    { $set: { _id: idCompany, name: companyName, address, email, tel, employees } }, // spotlight
                    { new: true }).exec();
        res.json({ success: true, employeeCreated });
    } catch(err) {
        res.status(400).json({ error: "Invalid request, something went wrong!", err });
    }
});

You could throw some specific custom errors in the try block if you find that necessary.如果您认为有必要,您可以在try块中抛出一些特定的自定义错误。

You could simply make the functions where your promises are running async and so, you could await for the promises to resolve.您可以简单地使您的承诺运行的功能异步,因此您可以等待承诺解决。

For example, in your route use this:例如,在你的路线中使用这个:

router.post('/', async (req, res) => {

and then when performing an async operation, use this:然后在执行异步操作时,使用这个:

const company = await Companies.findOne({ _id: idCompany }).exec();

Also, I would suggest you to wrap this with try and catch statments另外,我建议你用 try 和 catch 语句来包装它

Hope it helps!希望能帮助到你!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM