2016-06-15 45 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