使用水线寻找方法与承诺

时间:2014-06-16 14:41:58

标签: node.js sails.js waterline

从涉及数据库调用的方法返回响应时我感到困惑。

以下是我需要的样本......

service.js

 module.exports = {
    getUserStatus: function(userId){
      return User
             .find()
             .where({userId: userId)
             .exec(function(err, user){
               return user.status;
             }
    }
 }

在此 service.js 中,我应该获取用户的状态,如果我console.log(user.status)方法中的exec,那就打印好了(我获得了状态)

问题是我需要service.js以外的结果:

controller.js

// this code is extracted from longer file, just for demo purpose.
// userService is required 'service.js'
index: function(req, res) {
   var status = userService.getUserStatus(req.session.User.id);
   console.log(status);
   return res.view({userStatus: status});
}

如果我console.log(status)在这里,它将是未定义的。 我猜它与promises和stuff有关(因为异步调用),但不确定什么是正确的方法。

1 个答案:

答案 0 :(得分:2)

getUserStatus包含异步代码,因此需要回调:

 module.exports = {
    getUserStatus: function(userId, cb){
      User.findOne().where({userId: userId}).exec(function(err, user){
          if (err) return cb(err);
          return cb(null, user.status);
      });
    }
 }

然后在使用它的代码中:

index: function(req, res) {
   userService.getUserStatus(req.session.User.id, function(err, status) {
       // If an error was returned from the service, bail out
       if (err) {return res.serverError(err);}
       console.log(status);
       return res.view({userStatus: status});
   });
}

请注意使用findOne代替find; find将返回一个数组。

另一种方法是从服务功能返回一个承诺,并使用.then().fail()链接您的控制器代码:

 module.exports = {
    getUserStatus: function(userId, cb){
      return User.findOne().where({userId: userId});
    }
 }

index: function(req, res) {
   userService.getUserStatus(req.session.User.id)
       .then(function(user) {
           console.log(user.status);
           return res.view({userStatus: user.status});
       })
       .fail(function(err) {
           return res.serverError(err);
       });
   });
}

这是一个偏好问题,但我认为第一种方法更好,特别是在你的情况下,因为它允许服务调用只传递status,而不是整个用户对象。通常,习惯Node中的标准(err, result)回调方法可以很好地为您服务。