2016-06-15 140 views
0

我最近开始使用承诺,但我仍然没有得到一些东西。在承诺链中获得以前的结果(Q承诺)

让我给你下面的例子。

在节点& Mongo应用程序我试图实现一个操作,用jwt令牌来验证用户。该请求有两个参数userNamepassWord。我需要做的是:

1)检查,如果用户在数据库中存在 2)如果用户存在验证,如果从数据库中哈希密码相匹配从请求以纯文本提供的密码 3)如果两个密码匹配,从我从数据库获得的用户对象中生成一个jwt令牌。

对于步骤1)我已配置猫鼬使用Q承诺。对于步骤2)我正在使用bcrypt来比较这两个密码,并且对于步骤3)我正在使用节点jwt包生成令牌。

我已经分离出这样的代码(这只是一个概念证明):

// *** INSIDE AN API OBJECT *** // 

action : function(req, res) { 
      return User.findOne({ userName : req.body.userName }).exec() 
        .then(function(user){ 
         // If the user doesn't exist return invalid credentials 
         var defer = Q.defer(); 
         if (user) defer.resolve(user); 
         else defer.reject(new CError(400, E.INVALID_CREDENTIALS)); 
         return defer.promise; 
         // returns user 
        }) 
        .then(function(user){ 
         // See if the password matches the hash 
         return Q.nfcall(bcrypt.compare(req.body.passWord, user.passWordHash); 
         // Returns true || false 
        }) 
        .then(function(result){ 
         // How do I obtain the user that was calculated two levels before ?? 
         if (result) { 
          return Q.nfcall(jwt.sign, /* user */ , config.secret, {}); 
         } else { 
          return Q.defer().reject(new CError(400, E.INVALID_CREDENTIALS)); 
         } 
        }) 
        .then(function(token){ 
         res.json({token: token}); 
        }) 
        .catch(function(err){ 
         if (err instanceof CError) { 
          res.status(err.status).json({ error : err.message }); 
         } else { 
          res.status(500).json({ error : err.toString() }); 
         } 
        }) 
        .done(); 

     }, 

“问题”我有现在的问题是,第三then(),一个我应该产生jwt令牌我没有user的访问权限,它被计算在上面的两个级别。

我该如何克服这个限制?

我有一些解决方案,但我不喜欢它们。实现这一目标的标准方式是什么(如果存在这种情况)?

+0

你似乎只有1个异步调用(猫鼬抓取) - 为什么你使用这么多“然后”调用? – Amit

+0

关于'return Q.defer()。reject(...)',那应该是'return Q.reject(...);'或者只是'throw ...;'。你的第一个'then'回调根本不应该使用任何延迟,你可以简单地'if(user)return user;否则抛出新的CError(...);'。您可以通过在第一个回调中将'bcrypt.compare'调用替换为'return user'来将它与第二个回调合并。 – Bergi

+0

bcrypt.compare和jwt.sign也是异步的。 –

回答

0

我做了一个临时变量来存储它们..不知道这是否是正确的方法,但它一直在为我完美地工作。

//in beginning of your function make the variable 
    let _members; 

    //promise chain 
    .then(members=> { 
      //store it in the variable and you can use it later 
     _members = members 
    } 
+0

提示:事实并非如此。 – Bergi

+0

@Bergi照顾解释为什么不.. ..? – joe

+0

@Bergi我读了正确的方法来做到这一点,它似乎令人困惑..我怎么做呢? – joe