【问题标题】:How to handle Recursive Promise如何处理递归承诺
【发布时间】:2017-03-26 12:04:39
【问题描述】:
function Auth() {
    this.accessTokenError = false;

}
Auth.prototype.validateToken = function (accessToken, refreshToken) {
    var token;
    var self = this;
    return new Promise(function (resolve, reject) {
        AuthCron.secret()
            .then(function (secret) {

                if (self.accessTokenError) {
                    token = refreshToken;
                    secret = secret.substr(0, secret.length / 2);
                }
                else
                    token = accessToken;
                JWT.verify(token, secret, function (error, decoded) {
                    console.log(error, decoded);
                    if (error) {
                        if (!self.accessTokenError) {
                            self.accessTokenError = true;
                             // I don't know how to handle  this
                            self.validateToken(accessToken, refreshToken)
                        }
                        else {
                            self.accessTokenError = false;
                            reject(error);
                        }
                    }
                    else
                        resolve(decoded.user);
                });

            })
            .catch(function (err) {

                reject(err)
            });
    })
};

我对如何处理递归承诺有点困惑。这里的问题是第一个承诺永远不会解决或拒绝。处理这种情况的最佳方法是什么?如果访问令牌已过期或无效,则此函数接受两个令牌,然后验证刷新令牌,如果刷新令牌也无效,则承诺应拒绝。

【问题讨论】:

  • 你能重构上面的代码吗
  • 在单独的函数中仅承诺 JWT.verifynew Promise。然后调用它并使用then 回调来处理其他所有事情
  • 我无法在上面进行重构,因为如果出现错误,我必须再次调用该 jwt 函数以获取刷新令牌
  • 按照 Bergi 的建议行事不会阻止递归调用错误。事实上,它会有很大帮助。

标签: javascript node.js express callback promise


【解决方案1】:

对于这样的问题,通常最好将 Promise 的创建与更高阶的应用程序逻辑分开。这是通过在可能的最低级别做出承诺来完成的——在这种情况下是JWT.verify()

JWT.verifyAsync = function(token, secret) {
    return new Promise((resolve, reject) => {
        JWT.verify(token, secret, (error, decoded) => {
            error ? reject(error) : resolve(decoded);
        });
    });
};

现在,您仍然可以编写 Auth.prototype.validateToken() 方法以递归方式执行其尝试,但是由于最多只有 两个 级递归,因此硬编码要简单得多两者都尝试使用(伪代码)first_try().catch(() => second_try())。作为奖励,不再需要那个尴尬的 .accessTokenError 布尔值。

这里是完整的:

Auth.prototype.validateToken = function(accessToken, refreshToken) {
    return AuthCron.secret()
    .then(secret => {
        return JWT.verifyAsync(accessToken, secret) // first try
        .catch(() => JWT.verifyAsync(refreshToken, secret.substr(0, secret.length / 2))); // second try
    })
    .then(decoded => decoded.user);
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-29
    • 2016-04-02
    • 2014-02-04
    • 1970-01-01
    • 2016-12-02
    • 2016-12-23
    • 2017-01-31
    • 1970-01-01
    相关资源
    最近更新 更多