Как перенести мои цепочки транзакций mongoose PROMISE в поток ASYNC / AWAIT? - PullRequest
0 голосов
/ 03 июля 2019

Я создал API, который интегрирует ответы базы данных в поток обещаний, но я думаю, что интерпретация кода сложна, и я считаю, что асинхронный / ожидающий подход может улучшить как понимание, так и сам код.

API встроен в NodeJS с использованием mongoose 5.6.1 и экспресс 4.17.1.

Можете ли вы помочь мне улучшить это?

Ниже приведен 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 }));
});

Привет.

Ответы [ 2 ]

0 голосов
/ 03 июля 2019

Один из ключей к использованию обещаний с мангустом - использование метода exec:

Ваш код может выглядеть примерно так (не проверено):

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

Вы можете выбросить некоторые специфические пользовательские ошибки в блок try, если сочтете это необходимым.

0 голосов
/ 03 июля 2019

Вы можете просто сделать функции, в которых ваши обещания выполняются асинхронно, и поэтому вы можете дождаться разрешения обещаний.

Например, в вашем маршруте используйте это:

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

и затем при выполнении асинхронной операции используйте это:

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

Кроме того, я бы посоветовал вам обернуть это попытками и поймать статистику

Надеюсь, это поможет!

...