我有来自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
});
});
答案 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
模式。