我最近開始使用承諾,但我仍然沒有得到一些東西。在承諾鏈中獲得以前的結果(Q承諾)
讓我給你下面的例子。
在節點& Mongo應用程序我試圖實現一個操作,用jwt令牌來驗證用戶。該請求有兩個參數userName
和passWord
。我需要做的是:
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
的訪問權限,它被計算在上面的兩個級別。
我該如何克服這個限制?
我有一些解決方案,但我不喜歡它們。實現這一目標的標準方式是什麼(如果存在這種情況)?
你似乎只有1個異步調用(貓鼬抓取) - 爲什麼你使用這麼多「然後」調用? – Amit
關於'return Q.defer()。reject(...)',那應該是'return Q.reject(...);'或者只是'throw ...;'。你的第一個'then'回調根本不應該使用任何延遲,你可以簡單地'if(user)return user;否則拋出新的CError(...);'。您可以通過在第一個回調中將'bcrypt.compare'調用替換爲'return user'來將它與第二個回調合並。 – Bergi
bcrypt.compare和jwt.sign也是異步的。 –