我已经从游戏开发转向编写支持后端。到目前为止,一切似乎都很顺利,但是当我开始编写一个 friend 系统时,我遇到了这个对我来说似乎很脏的函数流程。而且我敢肯定,我现在只是在拼凑它。任何 node.js 向导会告诉我如何改进它吗?
相当确定我也应该在 Redis 中缓存播放器查找。
acceptfriend: function(req, res){
//Find our user
User.findById( req.decoded._id, function(err, user){
//error occured
if(err){
return res.status(401).send(err);
}
//no user found
if(!user){
return res.status(401).json({
succes: false,
message: 'no user found with that id'
} );
}
//Does the request exist?
if( !_.any( user.social.friendRequests, {id: req.params.id} ) ){
return res.status(401).json( {
succes: false,
message: 'friend request not found'
} );
}
//find the user that belongs to the request
User.findById( req.params.id, function(err, friend){
//error occured
if(err){
return res.send(err);
}
//user doesnt exist
if(!friend){
return res.status(401).json({
succes: false,
message: 'no user found with that id'
} );
}
//Pull the request from the friendRequests array
user.social.friendRequests.pull( req.params.id );
//Add the friend
user.social.friends.addToSet( {
user_id: friend._id,
name: friend.username,
corp: 'n/a'
} );
//Add the user to the friends list as well
friend.social.friends.addToSet({
user_id: user._id,
name: user.username,
corp: 'n/a'
});
//save the docs
user.save();
friend.save();
} );
//return success
return res.status(200).json({
success: true,
message: 'friend succesfully added'
});
} );
}
最佳答案
1- 首先,你有一个很大的功能。你必须把它分成一些功能。这样做,您就有可能使用任何测试框架对其进行测试。
2- 将错误响应的句柄委托(delegate)给 Controller 。
from -> return res.status(401).send(err);
to (with Promises)-> deferred.reject(err);
to (normal way) -> throw new Error(err);
3- 您可以使用 Promises 来管理 Node 的异步行为以清除代码。 我创建了一个示例,也许第一次无法正常工作,请随时修复不正确的引用。 User ref,'acceptfriend' 方法...
要点:https://gist.github.com/aitoraznar/b7099ad88ead0cdab256
var Promise = require('bluebird');
var _ = require('lodash');
//var User = app.models.User;
var ERRORS = {
userNotFoundError: {
code: 401,
success: false,
message: 'no user found with that id'
},
friendRequestNotFoundError: {
code: 401,
success: false,
message: 'friend request not found'
},
friendNotFoundError: {
code: 401,
success: false,
message: 'no friend found with that id'
}
}
var SUCCESS_MESSAGES= {
friendAddedSuccessfully: {
success: true,
message: 'friend succesfully added'
}
};
var userDAO = {
/*
*
*/
getUserById: function(id) {
var deferred = Promise.pending();
User.findById(id, function(err, user) {
//error occured
if (err) {
err.code = 401;
return deferred.reject(err);
}
//no user found
if (!user) {
return deferred.reject(ERRORS.userNotFoundError);
}
deferred.resolve(user);
});
return deferred.promise;
},
/*
* Does the request exist?
*/
checkFriendRequest: function(user, friendId) {
var deferred = Promise.pending();
if (userDAO.haveFriendRequestFrom(user, friendId)) {
deferred.resolve(user, friendId);
} else {
return deferred.reject(ERRORS.friendRequestNotFoundError);
}
return deferred.promise;
},
/*
*
*/
haveFriendRequestFrom: function(user, friendId) {
return _.any(user.social.friendRequests, {id: friendId });
},
/*
*
*/
getFriend: function(user, friendId) {
var deferred = Promise.pending();
userDAO.getUserById(friendId)
.then(function(friend) {
deferred.resolve(user, friend);
},
function(error) {
if (error === ERRORS.userNotFoundError) {
// Then the error is friend not found
// Override the error
error = ERRORS.friendNotFoundError;
}
return deferred.reject(error);
});
return deferred.promise;
},
/*
*
*/
makeFriendship: function(user, friend) {
var deferred = Promise.pending();
//Pull the request from the friendRequests array
user.social.friendRequests.pull(friend._id);
//Add the friend
user.social.friends.addToSet( {
user_id: friend._id,
name: friend.username,
corp: 'n/a'
} );
//Add the user to the friends list as well
friend.social.friends.addToSet({
user_id: user._id,
name: user.username,
corp: 'n/a'
});
//save the docs
user.save();
friend.save();
// Return the new friendship
var friendship = {
user: user,
friend:friend
};
deferred.resolve(friendship);
return deferred.promise;
},
/*
*
*/
friendRequestError: function(err) {
var deferred = Promise.pending();
// Propagate de error
deferred.reject(err);
return deferred.promise;
},
/*
*
*/
friendRequest: function(userId, friendId) {
var deferred = Promise.pending();
// Get user by ID
userDAO.getUserById(userId)
// Check if the user is able to add the friend
.then(userDAO.checkFriendRequest, userDAO.friendRequestError)
// Get the friend to add
.then(userDAO.getFriend, userDAO.friendRequestError)
// Make the friendship
.then(userDAO.makeFriendship, userDAO.friendRequestError)
// Response to the controller
.then(
function(friendship) {
// Resolve with new friendship
// This goes to 'success' function in controller
deferred.resolve(friendship);
}, function(error) {
// This goes to 'error' function in controller
deferred.reject(error);
})
return deferred.promise;
}
};
// Controller
var acceptfriend = function(req, res, next) {
var userId = req.decoded._id;
var friendId = req.params.id;
userDAO.friendRequest(userId, friendId)
.then(function(friendRequest) {
console.log('---> SUCCESS');
//return success
return res.status(200)
.json(SUCCESS_MESSAGES.friendAddedSuccessfully);
}, function(error) {
console.error('---> ERROR', error);
return res.status(error.code).json(error);
});
}
4- 在集合/表中创建数据库索引
问候, 艾特
关于javascript - 我怎样才能更好地优化这些数据库查询/功能流程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33734223/