我最近开始使用承诺,但我仍然没有得到一些东西。在承诺链中获得以前的结果(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也是异步的。 –