Node.js express с вызовами mongodb не завершает sh выполнение - PullRequest
0 голосов
/ 06 мая 2020

У меня есть функция .post, в которой я использую вызов mongodb, примерно так:

router.post('/insert')=>{

-findOne
// Some code
// with error return redirect('/error')

-Count
// with error return redirect('/error')

-Insert
// with error return redirect('/error') 
// with normal execution return redirect('/save')
}

Моя проблема в том, что после этого перенаправления выполнение этой функции не завершается sh. Итак, если то, что я проверяю после сбоя findOne, я не хочу go внутри Count или Insert

, обратите внимание, что я уже использую return redirect()

Edit Добавление кода:

router.post('/insert_article', common.restrict, (req, res) => {
db.findOne({
        _id: root_id
    },(err, item) => {
            if (item.language !== req.body.form_language) {
                req.session.message = req.i18n.__('Language does not match');
                req.session.message_type = 'Fail!';
                return res.redirect(req.app_context + '/insert');
            }
    })

 db.insert(doc, (err, newDoc) => {
                if (err) {
                    console.error('Error inserting document: ' + err);

                } else {
                  //some stuff
                  req.session.message = req.i18n.__('New article successfully created');
                  req.session.message_type = 'success';

                    // redirect to new doc
                  res.redirect(req.app_context + '/edit/' + newId);
                }
    })
}

Думаю, теперь стало яснее, когда этот «язык» не совпадает, я все равно не хочу вставлять эту вставку, и это продолжает делать это

1 Ответ

1 голос
/ 06 мая 2020

Изменить : с вашим обновленным кодом ясно, что вы пытаетесь вернуться из обратного вызова, обратитесь к фрагментам ниже

Без дополнительного кода трудно сказать, но мое лучшее предположение - что вы используете return redirect('/error') внутри функции обратного вызова (например, обратный вызов, предоставленный .then, если, например, вы используете обещания для своих методов базы данных), поэтому вместо возврата из общей функции вы возвращаетесь из обратный вызов, а затем продолжить через обработчик маршрута. В этом случае может быть лучше использовать обработчик маршрута asyn c, чтобы вы могли await вызвать свою базу данных, и return res.redirect, если что-то пойдет не так, что тогда будет действовать так, как вы ожидаете

Ваш код делает это там, где вы возвращаетесь из обратного вызова, поэтому выполнение внутри обработчика маршрута будет продолжено

router.post('/insert_article', common.restrict, (req, res) => {
    db.kb.findOne({
        _id: root_id
    },(err, item) => {
            if (item.language !== req.body.form_language) {
                req.session.message = req.i18n.__('Language does not match');
                req.session.message_type = 'Fail!';
                // the following line will return from your callback, NOT the route handler
                return res.redirect(req.app_context + '/insert');
            }
    })
    // because you returned from the callback, code here will continue to execute
});

вы можете вместо этого сделать это

router.post('/insert_article', common.restrict, (req, res) => {
    db.kb.findOne({
        _id: root_id
    },(err, item) => {
            if (item.language !== req.body.form_language) {
                req.session.message = req.i18n.__('Language does not match');
                req.session.message_type = 'Fail!';
                return res.redirect(req.app_context + '/insert'); // returns from callback, not the route handler
            }

            db.kb.insert(doc, (err, newDoc) => {
                if (err) {
                    console.error('Error inserting document: ' + err);
                } else {
                    //some stuff
                    req.session.message = req.i18n.__('New article successfully created');
                    req.session.message_type = 'success';

                    // redirect to new doc
                    res.redirect(req.app_context + '/edit/' + newId);
                }
                });
            }
    })
});

Но приведенное выше подход создаст «ад обратных вызовов», то есть обратные вызовы внутри обратных вызовов внутри обратных вызовов ... и так далее.

Лучше использовать обещания, а не функции обратного вызова, и синтаксис async/await:

router.post('/insert_article', common.restrict, async (req, res) => {
    try {
        const item = await db.kb.findOne({ _id: root_id });
        if (item.language !== req.body.form_language) {
            req.session.message = req.i18n.__('Language does not match');
            req.session.message_type = 'Fail!';
            return res.redirect(req.app_context + '/insert');
        }

        await db.kb.insert(doc); // if there is an error, it will be caught in the catch block
        req.session.message = req.i18n.__('New article successfully created');
        req.session.message_type = 'success';
        // redirect to new doc
        return res.redirect(req.app_context + '/edit/' + newId);
    } catch (e) {
        return res.redirect(req.app_context + '/insert');
    }
});
...