使节点Redis get()同步

我刚刚开始实施与节点的Redis。 在执行身份validation方法期间,我需要检查令牌是否存在于redis中,如果不是在redis中更新新令牌,并且在我的mongo数据库中,则需要编写一个大的callback块而不正确地获取结果。 我们怎样才能使redis得到callback的红色。 我们怎样才能使它同步。 示例代码如下。

module.exports.authenticate = function(request, response) { var reply = {}; if(UserSchema) { var UserModel, attributes; /** Registering User Model; **/ mongoose.model('user', UserSchema); UserModel = mongoose.model('user'); attributes = request.params; UserModel.findOne(attributes, "_id name email token", function(error, user) { if(!error && user) { var token; //delete user.password; token = user.token; /** Checking token exists in redis; **/ redisClient.get(token, function(error, value) { if(value === null && error === null) { /** Creating new token; **/ token = require('crypto').createHash('md5').update("" + (new Date()).getTime()).digest("hex"); user.token = token; /** Storing new token on redis; **/ setTokenOnRedis(token); /** Updating token in the user model; **/ UserModel.update({ _id : user._id}, { token : token }, function(error, user) { if(error !== null && user === null) { deleteTokenOnRedis(token); /** Error message; **/ reply = { error : true, code : "AUTH#001", msg : "User authentication failed, Please check user credentials." } response.send(reply); }else if(error === null && user !== null) { reply = user; response.send(reply); } }); }else if(value !== null) { reply = user; response.send(reply); }else { /** Error message; **/ reply = { error : true, code : "AUTH#001", msg : "User authentication failed, Please check user credentials." }; response.send(reply); } }); }else { /** Error message; **/ reply = { error : true, code : "AUTH#001", msg : "User authentication failed, Please check user credentials." } } }); }else { /** Error message; **/ reply = { error : true, code : "AUTH#001", msg : "User authentication failed, Please check user credentials." } response.send(reply); } }; 

不,您将无法使任何io电话同步,包括redis电话。 我知道唯一的同步io调用是文件系统和控制台。

但是,有一些编码技术可以用来使asynchronous编码更易于pipe理。

  • 早点回来,先检查一下错误。
  • 将重复的代码移动到一个单独的函数中,例如创build错误结构。
  • 使用这个asynchronous库: https : //github.com/caolan/async 。 特别是瀑布function可能在这里很方便。

我也认为你需要传入一个callback方法,因为它们是asynchronous的。

  • setTokenOnRedis(令牌);
  • deleteTokenOnRedis(令牌);

我已经重构了你的示例代码,希望它不应该缩进,更易读/可维护。 我没有使用asynchronous,我会留给你。

就个人而言,我发现最初的整个节点asynchronous编码模型非常令人沮丧,但是您已经习惯了。 过了一会儿,你学会了使用各种asynchronous编码模式,然后它变得可以忍受:)

一些您可能会发现有帮助的链接:

  • asynchronousnode.js调用中的error handling
  • Node.js最佳实践exception处理
  • 如何避免Node.js中asynchronous函数的长时间嵌套

重构代码:

 module.exports.authenticate = function(request, response){ authenticate(request, response, function(err, reply){ if(err){ reply = authenticationError(err); } response.send(reply); }); }; var authenticationError = function(internalmsg){ return { internalmsg : internalmsg, error : true, code : "AUTH#001", msg : "User authentication failed, Please check user credentials." }; }; var authenticate = function(request, response, callback) { if(UserSchema) { var UserModel, attributes; /** Registering User Model; **/ mongoose.model('user', UserSchema); UserModel = mongoose.model('user'); attributes = request.params; UserModel.findOne(attributes, "_id name email token", function(err, user) { if(err || !user){ return callback(err || "UserModel.findOne, no user"); } var token; //delete user.password; token = user.token; /** Checking token exists in redis; **/ redisClient.get(token, function(err, value){ if(err){ return callback(err); } if(value){ return callback(null, value); } /** Creating new token; **/ token = require('crypto').createHash('md5').update("" + (new Date()).getTime()).digest("hex"); user.token = token; /** Storing new token on redis; **/ setTokenOnRedis(token); /** Updating token in the user model; **/ UserModel.update({ _id : user._id}, { token : token }, function(err, user) { if(err || !user) { deleteTokenOnRedis(token); return callback(err || "UserModel.update, no user found"); } callback(null, user); }); }); }); } };