在承诺链中混合变量

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);
    }
};