Mongoose数据库查找方法之前节点功能完成



为什么下面的例子会在我的mongosedb查找函数完成之前返回节点中间件函数?我确信这是一个异步问题,但我有点不明白为什么。

中间件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: 'bclark@themindspot.com',
  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) }

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); 
    });
};

最后,考虑使用(自定义)Error对象而不是String消息,在谷歌上搜索原因解释。

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

在你的代码中,你称之为

var user = isUser(login),

根据You的说法,它应该返回isUser函数的结果,但执行过程为该函数提供了一个单独的线程,并继续执行下一条语句。在下一条语句中,用户是未定义的,因为它没有从函数isUser 返回任何内容

因此语句CCD_ 11变为真

为了避免此错误,您应该将isUser放在回调函数中

意味着限制执行,直到并且除非您从函数得到响应

最新更新