简体   繁体   English

如何更好地优化这些数据库查询/功能流?

[英]How can I better optimise these DB queries/function flow?

I've turned my hand from game dev to writing a supporting back-end. 我已将手从游戏开发转向编写支持后端。 Thus far everything seems to work out but when i got to writing a friend system i ran into this function flow which seemed very dirty to me. 到目前为止,一切似乎都有效,但是当我开始编写朋友系统时,我遇到了这个功能流程,这对我来说似乎很脏。 And i'm certain i'm just hacking it together at this point. 而且我确定我现在只是在一起攻击它。 Any node.js wizards about to tell me how I can improve this? 任何node.js向导都要告诉我如何改进这个?

Fairly certain i should be caching player lookups in Redis as well. 相当肯定我应该在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- First of all, you have a big function. 1-首先,你有一个很大的功能。 You have to split it into some functions. 你必须将它拆分成一些功能。 Doing this you gain the possibility to test them with any testing framework. 这样做可以使用任何测试框架测试它们。

2- Delegate the handle of error responses to the controller. 2-将错误响应句柄委派给控制器。

from -> return res.status(401).send(err);
to (with Promises)-> deferred.reject(err); 
to (normal way)   -> throw new Error(err); 

3- You can use Promises to manage the asynchronous behaviour of node to clear the code. 3-您可以使用Promises来管理节点的异步行为以清除代码。 I created an example, maybe is not working at first time, feel free to fix the incorrent references. 我创建了一个例子,也许是第一次没有工作,随时修复不正确的引用。 The User ref, the 'acceptfriend' method... 用户参考,'接受朋友'方法......

Gist: https://gist.github.com/aitoraznar/b7099ad88ead0cdab256 要点: 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- Create database indexes in the collection/table 4-在集合/表中创建数据库索引

Regards, Aitor 此致,Aitor

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM