我怎样才能在这里发现错误?

时间:2017-11-22 23:03:20

标签: javascript node.js express mongoose async-await

我有来自DB的路由器和两个acync提取。在这里捕获错误的正确方法是什么?

router.get('/restaurant/:id', async (req, res, next) => {
    var current_restaurant = await Restaurant.findOne({restaurantId: req.params.id}).exec();
    var products = await Product.find({restaurant: req.params.id}).exec();

    res.render('restaurant', {  
        user: req.user,
        csrfToken: req.csrfToken(),
        current_restaurant: current_restaurant,
        products: products
    });
});

2 个答案:

答案 0 :(得分:2)

如果您要使用await,那么您可以使用try / catch来拒绝您正在等待的任何一个承诺:

router.get('/restaurant/:id', async (req, res, next) => {
    try {
        let current_restaurant = await Restaurant.findOne({restaurantId: req.params.id}).exec();
        let products = await Product.find({restaurant: req.params.id}).exec();
        res.render('restaurant', {  
            user: req.user,
            csrfToken: req.csrfToken(),
            current_restaurant: current_restaurant,
            products: products
        });
     } catch(e) {
         // do whatever you want 
         console.log(e);
         res.sendStatus(500);
     }
});

您可以使用.then()将其与常规承诺编程进行比较:

router.get('/restaurant/:id', async (req, res, next) => {
    Promise.all([
        Restaurant.findOne({restaurantId: req.params.id}).exec(),
        Product.find({restaurant: req.params.id}).exec()
    ]).then([current_restaurant, products] => {
        res.render('restaurant', {  
            user: req.user,
            csrfToken: req.csrfToken(),
            current_restaurant: current_restaurant,
            products: products
        });
    }).catch(e => {
        // add your desired error handling here
        console.log(e);
        res.sendStatus(500);
    });
});

由于您的两个数据库请求彼此独立,因此第二个版本允许并行化数据库查询,实际运行速度可能稍快(取决于您的数据库)。

答案 1 :(得分:2)

或者:

try {
    var current_restaurant = await Restaurant.findOne({restaurantId: req.params.id}).exec();
    var products = await Product.find({restaurant: req.params.id}).exec();

    res.render('restaurant', {  
        user: req.user,
        csrfToken: req.csrfToken(),
        current_restaurant: current_restaurant,
        products: products
    });
} catch (err) {
    // Handle your errors here...
}

这是你的典型模式。根据您是否可以恢复并继续渲染(使用默认值或其他内容),您可能希望仅在try块中包含await调用(并在try块之前声明变量)。

否则,您正在等待承诺,因此如果您觉得更清楚,您仍然可以使用承诺.catch方法。

var current_restaurant = await Restaurant.findOne({restaurantId: req.params.id}).exec()
    .catch(err => { /* handle error here*/ });
var products = await Product.find({restaurant: req.params.id}).exec()
    .catch(err => { /* handle error here*/ });

但是,如果您仍然可以在catch代码中返回有效内容(例如,某种默认值或回退值),则此模式将非常有用。如果你在发生错误时需要摆脱整件事,这对你来说不会有用,你应该使用前面提到的try/catch模式。