【问题标题】:Node function finishing before Mongoose db find methodMongoose db find 方法之前的节点函数整理
【发布时间】:2013-06-25 05:14:03
【问题描述】:

为什么下面的示例会在我的 mongoose 数据库查找函数完成之前返回节点中间件函数?我确信这是一个异步问题,但我对为什么有点迷茫。

中间件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) }

【问题讨论】:

    标签: node.js mongodb database-connection mongoose


    【解决方案1】:

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

    ===

    完整的东西会变成下面这样。请注意,我遵循 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); 
        });
    };
    

    最后,考虑使用(自定义)错误对象而不是字符串消息,谷歌它以解释原因。

    【讨论】:

    • 谢谢。你的例子更能说明这个问题。我将添加一个指向我的 git 存储库的链接,这样您就可以看到实际的更改,但您几乎无法使用上面的代码。
    【解决方案2】:

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

    在你调用的代码中

    var user = isUser(login),

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

    所以声明if (!user) { 变为真

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

    意味着限制执行直到并且除非你得到函数的响应

    【讨论】:

      猜你喜欢
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多