2016-11-12 5 views
0
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) 
      }); 
    }) 
}; 

Я немного смущен тем, как обращаться с рекурсивным обещанием. Проблема здесь в первом обещании никогда не решает и не отвергает. Каков наилучший способ справиться с этой ситуацией? Эта функция принимает два токена, если токен доступа истек или недействителен, а токен обновления проверяется, если токен обновления также недействителен, тогда обещание отклонить.Как обращаться с рекурсивным обещанием

+2

Избегайте [ 'Promise' конструктор антипаттерн] (http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

может у рефакторинга выше кода – Rayees

+1

обещать только 'JWT.verify' с' новой Promise', в отдельной функции. Затем вызовите это и используйте обратные вызовы 'then' для всего остального – Bergi

ответ

0

С такими проблемами, как правило, лучше всего отделить создание обещаний от логики приложения более высокого порядка. Это делается путем пролонгации на максимально возможном уровне - 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 boolean.

Здесь в полном объеме:

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