Javascript 将函数结果传递给父函数

Javascript 将函数结果传递给父函数,javascript,node.js,mongodb,closures,mongoose,Javascript,Node.js,Mongodb,Closures,Mongoose,因此,我有一个用户对象检查现有记录的方法 User.findOrCreate = function(json){ User.findOne({'email' : json.email}, function(err, user){ if (!user){ user = new User({ id: json.id, email: json.email, f

因此,我有一个用户对象检查现有记录的方法

User.findOrCreate = function(json){
    User.findOne({'email' : json.email}, function(err, user){
        if (!user){
            user = new User({
                id: json.id,
                email: json.email,
                f_name: json.first_name,
                l_name: json.last_name,
                gender: json.gender,
                locale: json.locale
            });
            user.save(function(err){
                if (err) return handleError(err);
                return user;
            });
        } else {
            return user;
        }
    });
}
基本上,我想将变量“user”返回给findOrCreate方法,这样我就可以在另一个地方使用它,比如:

var user = User.findOrCreate(profile._json);

但是,当我注销时,user=未定义。在这方面有很多麻烦。有人能帮忙吗?

用户.getOrCreate函数没有任何
返回
语句,因此它当然会返回
未定义的
,事实上
findOne
是异步工作的,因此您的
getOrCreate
函数也应该是异步的,因此您可以将函数定义更改为:

User.findOrCreate = function(json, callback) {
而不是
返回用户您应该运行回调函数:

callback(user);
你不能这样做:

var user = User.findOrCreate(profile._json);
因为
User.findOne
的执行是异步的,所以当
findOrCreate
返回时,可能还没有执行
User.findOne

获取用户值的正确方法是在
findOrCreate
中使用另一个回调:

User.findOrCreate = function(json, callback){
    User.findOne({'email' : json.email}, function(err, user){
       if (!user){
           user = new User({
               id: json.id,
               email: json.email,
               f_name: json.first_name,
               l_name: json.last_name,
               gender: json.gender,
               locale: json.locale
            });
            user.save(function(err){
               if (err) return handleError(err);
               callback(user);
            });
        } else {
            callback(user);
        }
     });
};
正如你所见,处理所有这些回调会让你生气。如果您尚未尝试承诺,请查看Q库:

这会让你的生活变得轻松:

 var userPromise = User.findOrCreate(profile._json);
 /* then when you need a user */
 userPromise.done(function (user) { /* do something */ });
优点是Promissions附带了非常有用的抽象来处理异步代码的控制流,例如,使用Promissions,您可以编写
findOrCreate
,如下所示:

  User.findOrCreate = function(json) {
       return User.findOne({email:json.email}).then(createIfNull);
  };

其中
createIfNull
if
块中的代码(if
save
也会返回一个承诺。如果没有,您可以创建一个并返回它,请参见Q示例…文档不是很直观,但一旦您习惯了它,您就会发现它确实简化了所有回调混乱).

考虑您已经创建了一个内部函数的事实。在node.js中,您不能从函数返回异步结果,必须使用回调。