我在Node REST api中使用猫鼬诺言,并且我有很多相同的.catch块。
这是一条小路:
router.get('/', (req, res) => {
Post.find()
.populate('category', 'name')
.exec()
.then(posts => {
res.status(200).json(posts);
})
.catch(err => {
log.error(err);
res.status(500).json(err);
});
});
我有一些路由,在同一函数中,确切的.catch块会出现3次。 我可以在其中创建日志和结果的函数,然后将该函数传递给.catch吗?还是可以使用一些中间件?我该如何清理我的代码?
这里是一团糟:
router.delete('/:commentId', checkAuth, (req, res) => {
// Find the comment
Comment.findById(req.params.commentId).exec()
.then(comment => {
foundComment = comment;
// Delete the comment
Comment.deleteOne({ _id: req.params.commentId }).exec()
.then(result => {
if (result.deletedCount) {
// If the comment has replies, remove them as well
if (foundComment.replies.length > 0) {
Comment.deleteMany({ _id: { $in: foundComment.replies } }).exec()
.then(result => {
if (result.deletedCount) {
res.status(200).json({
deletedCount: result.deletedCount + 1
});
}
})
.catch(err => {
log.error(err);
res.status(500).json(err);
});
return;
}
res.status(200).json({
deletedCount: result.deletedCount
});
} else {
res.status(404).json({
message: `Comment with id ${req.params.commentId} doesn't exist.`
});
}
})
.catch(err => {
log.error(err);
res.status(500).json(err);
});
})
.catch(err => {
log.error(err);
res.status(500).json(err);
});
});
答案 0 :(得分:2)
返回Promise链中的每个Promises,以便将它们都绑在一起,使您可以在最后放置一个.catch
,如果里面有任何东西,它将运行:
router.delete('/:commentId', checkAuth, (req, res) => {
let foundComment;
Comment.findById(req.params.commentId).exec()
.then(comment => {
foundComment = comment;
return Comment.deleteOne({ _id: req.params.commentId }).exec();
})
.then(result => {
if (!result.deletedCount) {
res.status(404).json({
message: `Comment with id ${req.params.commentId} doesn't exist.`
});
return;
}
if (foundComment.replies.length <= 0) {
res.status(200).json({
deletedCount: result.deletedCount
});
return;
}
return Comment.deleteMany({ _id: { $in: foundComment.replies } }).exec()
.then(result => {
if (result.deletedCount) {
res.status(200).json({
deletedCount: result.deletedCount + 1
});
}
});
})
.catch(err => {
log.error(err);
res.status(500).json(err);
});
});
通常,如果可以帮助的话,请尽量避免嵌套.then
-扁平代码是更具可读性的代码。 async
/ await
将使事情变得更加清晰:
router.delete('/:commentId', checkAuth, async (req, res) => {
try {
const foundComment = await Comment.findById(req.params.commentId).exec();
const deleteOneResult = await Comment.deleteOne({ _id: req.params.commentId }).exec();
if (!deleteOneResult.deletedCount) {
res.status(404).json({
message: `Comment with id ${req.params.commentId} doesn't exist.`
});
return;
}
if (foundComment.replies.length <= 0) {
res.status(200).json({
deletedCount: result.deletedCount
});
return;
}
const deleteManyResult = await Comment.deleteMany({ _id: { $in: foundComment.replies } }).exec()
if (deleteManyResult.deletedCount) {
res.status(200).json({
deletedCount: deleteManyResult.deletedCount + 1
});
}
} catch (err) {
log.error(err);
res.status(500).json(err);
}
});
答案 1 :(得分:1)
我建议更改您的代码以使用async/await
并使用try/catch
来处理错误。
router.get('/', async (req, res) => {
try {
let posts = await Post.find().populate('category', 'name');
let comment = await Comment.findById(req.params.commentId);
if (!comment) {
return res.status(404).json({
message: `Comment with id ${req.params.commentId} doesn't exist.`
});
}
// Another query...
res.status(200).json(posts);
} catch(err) {
log.error(err);
res.status(500).json(err);
});
});
答案 2 :(得分:0)
您可以将函数直接传递给.catch
,例如:
function handleError(err) {
console.error('the error:', err.message)
}
const promise = new Promise((resolve, reject) => reject(new Error('your error')))
promise.catch(handleError)