【问题标题】:Mixing in variables in a promise chain [duplicate]在承诺链中混合变量[重复]
【发布时间】:2016-12-05 18:16:43
【问题描述】:

所以我有一个承诺链来解决我正在经历的某个回调地狱。

链条是这样的:

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 返回一个返回我的用户的承诺。我需要“混合”密码以进行身份​​验证。鉴于这是我对 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');
        }
    });
};

【问题讨论】:

标签: javascript ecmascript-6 es6-promise


【解决方案1】:

您可以使用内联函数来做到这一点:

.then(value => authenticateUser(value, password)) // mix in password here?

不过,您必须更新 authenticateUser,因为您问题中的签名是不接受密码的旧式 NodeJS 回调,而不是要传递给 then 的函数。

也许是这样的(见 cmets,但也请继续阅读):

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 上,但它不应该解决 null 为用户,所以您的 then 回调应该能够假设用户是有效的(这简化了上述内容)。如果身份验证失败,authenticate 应该拒绝

还要注意,由于authenticate 返回一个承诺,我们不应该在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);
    }
};

【讨论】:

  • 我注意到你只有在那里有价值。函数签名不是把错误放在第一位吗?
  • @MathieuBertin:不。那是老式的 NodeJS 回调。使用 Promises 时,成功和失败采用不同的路径。解析成功,它遵循then 线索(传递给then 的第一个函数)。拒绝是错误的,它遵循catch 线索(或传递给then 的第二个函数)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
  • 2016-02-22
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多