在承诺链中混合变量
Mixing in variables in a promise chain
所以我有一个 promise 链,可以解决我遇到的某个回调地狱。
这是链条的样子:
server.exchange(oauth2orize.exchange.password(
function(client, email, password, scope, done) {
users.findOne({email: email})
.then(authenticateUser) // mix in password here?
.then(deleteExistingTokens)
.then(createAndSaveNewTokens)
.then(function(results){
done(null, results[0], results[1], {'expires_in': tokenLife});
}).catch(err => {done(err);});
}));
所以users.findOne returns returns 我的用户的承诺。我需要 'mix in' 密码进行身份验证。鉴于这是我对 authenticateUser 的定义,我将如何在链中插入新变量?
const authenticateUser = (err, user) => { // add password here?
return Promise((resolve, reject) => {
if (!user) {
reject('User not found');
}
try {
return User(user).authenticate(password)
.then((result) => {
if (result) {
resolve(user);
} else {
reject('Invalid password');
}
});
}
catch (err) {
reject('Invalid user');
}
});
};
您可以使用内联函数来做到这一点:
.then(value => authenticateUser(value, password)) // mix in password here?
不过,您必须更新 authenticateUser
,因为您问题中的签名是旧式 NodeJS 回调,它不接受密码,而不是要传递给 then
.
也许是这样的(查看评论,但也请继续阅读):
const authenticateUser = (user, password) => {
// We shouldn't need to create a new promise here, we have one
// from `authenticate` below we can use
return Promise((resolve, reject) => {
if (!user) { // This shouldn't be
reject('User not found'); // necessary...?
} // ...
try {
// No `return` on th enext line, doesn't do anything
// useful in the Ppromise init callback
User(user).authenticate(password)
.then((result) => {
if (result) {
resolve(user);
} else {
reject('Invalid password');
}
});
}
catch (err) {
reject('Invalid user');
}
});
};
请注意,在上面,我将 then
回调中的逻辑单独留在 authenticate
上,但它不应该是 resolving对于用户 null
,因此您的 then
回调应该能够假定用户有效(这简化了上述内容)。如果身份验证失败,authenticate
应该拒绝。
另请注意,由于 authenticate
returns 一个承诺,我们不应该在 authenticateUser
.
中创建一个新的承诺
这是我对全新 authenticateUser
的看法:
const authenticateUser = (user, password) => {
// This `try` is only here to guard against possible exceptions
// from `User` or `authenticate`
try {
return User(user).authenticate(password);
}
catch (Exception e) {
return Promise.reject(e);
}
};
所以我有一个 promise 链,可以解决我遇到的某个回调地狱。
这是链条的样子:
server.exchange(oauth2orize.exchange.password(
function(client, email, password, scope, done) {
users.findOne({email: email})
.then(authenticateUser) // mix in password here?
.then(deleteExistingTokens)
.then(createAndSaveNewTokens)
.then(function(results){
done(null, results[0], results[1], {'expires_in': tokenLife});
}).catch(err => {done(err);});
}));
所以users.findOne returns returns 我的用户的承诺。我需要 'mix in' 密码进行身份验证。鉴于这是我对 authenticateUser 的定义,我将如何在链中插入新变量?
const authenticateUser = (err, user) => { // add password here?
return Promise((resolve, reject) => {
if (!user) {
reject('User not found');
}
try {
return User(user).authenticate(password)
.then((result) => {
if (result) {
resolve(user);
} else {
reject('Invalid password');
}
});
}
catch (err) {
reject('Invalid user');
}
});
};
您可以使用内联函数来做到这一点:
.then(value => authenticateUser(value, password)) // mix in password here?
不过,您必须更新 authenticateUser
,因为您问题中的签名是旧式 NodeJS 回调,它不接受密码,而不是要传递给 then
.
也许是这样的(查看评论,但也请继续阅读):
const authenticateUser = (user, password) => {
// We shouldn't need to create a new promise here, we have one
// from `authenticate` below we can use
return Promise((resolve, reject) => {
if (!user) { // This shouldn't be
reject('User not found'); // necessary...?
} // ...
try {
// No `return` on th enext line, doesn't do anything
// useful in the Ppromise init callback
User(user).authenticate(password)
.then((result) => {
if (result) {
resolve(user);
} else {
reject('Invalid password');
}
});
}
catch (err) {
reject('Invalid user');
}
});
};
请注意,在上面,我将 then
回调中的逻辑单独留在 authenticate
上,但它不应该是 resolving对于用户 null
,因此您的 then
回调应该能够假定用户有效(这简化了上述内容)。如果身份验证失败,authenticate
应该拒绝。
另请注意,由于 authenticate
returns 一个承诺,我们不应该在 authenticateUser
.
这是我对全新 authenticateUser
的看法:
const authenticateUser = (user, password) => {
// This `try` is only here to guard against possible exceptions
// from `User` or `authenticate`
try {
return User(user).authenticate(password);
}
catch (Exception e) {
return Promise.reject(e);
}
};