为什么下面的例子会在我的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消息,在谷歌上搜索原因解释。
在你的代码中,你称之为
var user = isUser(login),
根据You的说法,它应该返回isUser
函数的结果,但执行过程为该函数提供了一个单独的线程,并继续执行下一条语句。在下一条语句中,用户是未定义的,因为它没有从函数isUser
返回任何内容
因此语句CCD_ 11变为真
为了避免此错误,您应该将isUser
放在回调函数中
意味着限制执行,直到并且除非您从函数得到响应