如何处理递归承诺

时间:2016-11-12 10:21:43

标签: javascript node.js express callback promise

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

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

1 个答案:

答案 0 :(得分:0)

对于这样的问题,通常最好将promises的创建与更高阶的应用程序逻辑分开。这是通过在尽可能最低的级别进行宣传来完成的 - 在这种情况下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()方法来递归执行其尝试,但是,因为只有最多两个级别的递归,所以它更难以简化-code都尝试使用(伪代码)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);
};