2013-06-25 27 views
1

为什么下面的示例可能在我的猫鼬 db查找函数完成之前返回节点中间件功能?我相信这是一个异步问题,但我为什么有点失落。在Mongoose db查找方法之前完成节点功能

中间件js文件

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

function isUser(login){ 
    var UsersSchema = new Schema({ 
     user:  String, 
     user_type: String, 
     password: String, 
     first_name: String, 
     middle_name:String, 
     last_name: String, 
     birth_date: Date, 
     join_date: Date 
    }); 

    var UserModel = mongoose.model('users', UsersSchema); 

    mongoose.connect('mongodb://localhost/identity'); 
    mongoose.model('users', UsersSchema); 
    var db = mongoose.connection; 
    db.on('error', console.error.bind(console, 'connection error: ')); 
    db.once('open', function cb() {  
     UserModel.findOne({'user': login}, function (err, user){ 
      if (err){ throw err; } 
      console.log('connected to user db and preformed lookup.'); 
      console.log(user); 
      return user; 
     }); 
    }); 
} 

module.exports.authenticate = function (login, password, cb) { 
    var user = isUser(login), 
     msg;  
    console.log(user); 
    if (!user) { 
     msg = 'Invalid User'; 
     cb(null, msg); 
     return; 
    } 
    if (user.password != password) { 
     msg = 'Invalid Password'; 
     cb(null, msg); 
     return; 
    } 
    cb(user, null); 
}; 

控制台输出

undefined 
Login Failed! : Invalid User 
connected to user db and preformed lookup. 
{ _id: 51c8e16ce295c5b71ac6b229, 
    user: '[email protected]', 
    user_type: 'admin_master', 
    password: 'enter', 
    first_name: 'Brandon', 
    middle_name: 'Laurence', 
    last_name: 'Clark', 
    birth_date: Fri Mar 19 1982 00:00:00 GMT-0800 (PDT), 
    join_date: Wed Jun 26 2013 00:00:00 GMT-0700 (PDT) } 

回答

2

db.once和UserModel.findOne是异步函数,因此为什么要提供一个匿名函数即如果你想让你的isUser函数'返回'这些异步函数的结果,你还必须使它回调。

更换 function isUser(login){function isUser(login, callback){

return user;callback(user)

它也建议不要扔在异步代码中的错误,而是把它们有回调,类似于db.once和UserModel.find做,像这样:

删除 if (err){ throw err; } 和更换回调以上 callback(err, user);

当你在它,因为你没有做的错误或用户什么了,你还不如叫UserModel.findOne({'user': login}, callback);

===

完整的东西将成为以下内容。请注意,我遵循回调(err,result)约定。

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

function isUser(login, callback){ 
    var UsersSchema = new Schema({ 
     user:  String, 
     user_type: String, 
     password: String, 
     first_name: String, 
     middle_name:String, 
     last_name: String, 
     birth_date: Date, 
     join_date: Date 
    }); 

    var UserModel = mongoose.model('users', UsersSchema); 

    mongoose.connect('mongodb://localhost/identity'); 
    mongoose.model('users', UsersSchema); 
    var db = mongoose.connection; 
    db.on('error', console.error.bind(console, 'connection error: ')); 
    db.once('open', function cb() {  
     UserModel.findOne({'user': login}, callback); 
    }); 
} 

module.exports.authenticate = function (login, password, cb) { 
    var user = isUser(login, function(err, user) { 
     if (err) { 
      cb(err); 
     } 
     console.log(user); 
     if (!user) { 
      msg = 'Invalid User'; 
      cb(msg); 
      return; 
     } 
     if (user.password != password) { 
      msg = 'Invalid Password'; 
      cb(msg); 
      return; 
     } 
     cb(null, user); 
    }); 
}; 

最后,考虑使用(自定义)错误对象而不是String消息,谷歌解释为什么。

+0

谢谢。你的例子让这个问题变得更有意义。我将添加一个链接到我的git repo,这样你就可以看到实际的变化,但是你已经接近死于上面的代码。 –

1

是的,这是一个异步的问题。你可能知道,Node.js的每一个动作都有一个单独的线程

在你的代码中调用

var user = isUser(login),

根据你就应该从isUser函数返回的结果,但在执行给这个函数单独的线程,它会继续到下一个语句。 作为下一个语句的用户是不确定的,因为它没有从该函数返回任何isUser

这样的声明if (!user) {为真

避免这种错误,你应该把isUser在回调函数

表示限制执行,直到并且除非得到来自函数的响应

+0

差不多但并不完全。 – mtsr

相关问题