我正在编写一个非常简单的RESTful API,使用Node.js,restify和mongoose,但代码变得越来越复杂。这是由我每次进行查询时必须执行的所有检查引起的。例如,下一个代码显示端点POST / users /:user1 / follow /:user2的控制器。
exports.followUser = function(req, res, next) {
User.findOne({ username: req.params.user1 }, function(err, user1) {
if (err) {
res.status(500);
res.json({ type: false, data: 'Error occurred: ' + err });
} else {
if (user1) {
User.findOne({ username: req.params.user2 }, function(err, user2) {
if (err) {
res.status(500);
res.json({ type: false, data: 'Error occurred: ' + err });
} else {
if (user2) {
user2.followers.push(user1);
user2.save();
res.json({
type: true,
data: 'User ' + req.params.user1 + ' is now following user ' + req.params.user2
});
} else {
res.json({
type: false,
data: 'User ' + req.params.user2 + ' not found'
});
}
}
});
} else {
res.json({
type: false,
data: 'User ' + req.params.user1 + ' not found'
});
}
}
});
};
如何简化此代码?正如您所看到的,我正在检查每个findOne的结果,以了解用户是否存在,并且我还为每个错误返回json答案,但这很乏味。有没有办法自动化这个?
答案 0 :(得分:1)
你可以使用Mongoose的承诺来清理它。类似的东西:
exports.followUser = function(req, res, next) {
User.findOne({
username: req.params.user1
}).exec().then(function(user1) {
if (user1 === null) {
throw new Error('User ' + req.params.user1 + 'not found');
}
return User.findOneAndUpdate({
username: req.params.user2
}, {$push: {followers: user1}}).exec();
}).then(function(user2) {
if (user2 === null) {
throw new Error('User ' + req.params.user2 + ' not found');
}
res.json({
type: true,
data: 'User ' + req.params.user1 + ' is now following user ' + req.params.user2
});
}, function(err) {
res.status(500);
res.json({ type: false, data: 'Error occurred: ' + err });
});
};
答案 1 :(得分:1)
Promises有助于使代码更具可读性,我还看到了另外两种简化代码的方法。你可以通过使用内置的restify错误类型处理错误来减少几行并且可能获得一些易读性
其次,您可以更新user2而不是获取他/她并简化您的if语句。另外,您还可以获得额外的错误检查,以确保您在保存时丢失了。我想出了类似的东西:
exports.followUser = function(req, res, next) {
User.findOne({username: req.params.user1}, function (err, user1) {
next.ifError(err);
if (!user1)
return next(new restify.NotFoundError('User ' + req.params.user1 + ' not found'));
User.update({username: req.params.user2}, {$push: {followers: user1}}, function (err, updated) {
next.ifError(err);
if(!updated)
return next(new restify.NotFoundError('User ' + req.params.user2 + ' not found'));
return res.send({
type: true,
data: 'User ' + req.params.user1 + ' is now following user ' + req.params.user2
});
next();
});
});
};
如果您希望在未找到用户时保留使用额外信息返回200响应的约定,则可以创建自定义错误类:
var restify = require('restify');
var util = require('util');
function MyError(message) {
restify.RestError.call(this, {
restCode: 'MyError',
statusCode: 200,
message: message,
constructorOpt: MyError
});
this.name = 'MyError';
};
util.inherits(MyError, restify.RestError);
然后根据文档为该错误创建一个全局处理程序,这样您就可以按照自己的方式返回json格式。