将函数结果传递给父函数

时间:2013-05-25 18:36:37

标签: javascript node.js mongodb closures mongoose

所以我有这个方法让User对象检查现有记录。

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 = undefined。这有很多麻烦。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

User.getOrCreate函数没有任何return语句,因此它当然会返回undefined,实际上findOne正在异步处理,因此您getOrCreate函数也应该是异步的,所以你可以将函数定义改为:

User.findOrCreate = function(json, callback) {

而不是return user;你应该运行回调函数:

callback(user);

答案 1 :(得分:0)

你不能这样做:

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库:http://documentup.com/kriskowal/q/

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

 var userPromise = User.findOrCreate(profile._json);
 /* then when you need a user */
 userPromise.done(function (user) { /* do something */ });

优点是promises带有非常有用的抽象来处理异步代码的控制流,例如使用你可以写findOrCreate的承诺:

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

其中createIfNullif块中的代码(如果save也返回一个承诺,那么事情很简单..如果没有,你可以创建一个并返回它,请参阅Q示例......文档不是很直观,但是一旦你习惯了它,你会发现它真的简化了所有的回调混乱。)