在promise链中混合变量

Mat*_*tin 1 javascript ecmascript-6 es6-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);});
    }));
Run Code Online (Sandbox Code Playgroud)

所以users.findOne返回一个返回我的用户的promise.我需要'混合'密码进行身份验证.鉴于这是我对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');
        }
    });
};
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

您可以使用内联函数执行此操作:

.then(value => authenticateUser(value, password)) // mix in password here?
Run Code Online (Sandbox Code Playgroud)

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');
        }
    });
};
Run Code Online (Sandbox Code Playgroud)

需要注意的是在上面的,我已经离开了逻辑的then回调authenticate独自一人,但它不应该被解决null用户,所以你的then回调应该能够假定用户是有效的(这简化以上).如果身份验证失败,authenticate则应拒绝.

另请注意,既然authenticate返回了一个promise,我们就不必创建一个新的promise 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);
    }
};
Run Code Online (Sandbox Code Playgroud)