在继续之前等待API调用返回

时间:2017-12-02 20:33:29

标签: javascript vuejs2 axios

我在javascript中非常弱,但我想我明白出了什么问题。只是不够流利,不知道如何解决它,甚至不知道如何正确地编写它。我有一个VueJS应用程序,它向access_token的API发送请求。当access_token到期时,它会向API发送refresh_token并获取新的access_token。我希望它重做它过期时运行的请求。使用下面的代码我得到奇怪的行为。当它到达401时,我可以看到它访问/token端点并获得新的access_token但是下一次调用/brewery时使用旧的access_token。在调用/brewery最终使用新access_token并且循环停止之前,这种情况发生了大约5次。我的猜测是,当我致电this.loaded()时,auth.refreshToken()的来电尚未结束?

loaded(access_token){
        var headers;
        if(access_token)
        {
            headers = { 'Authorization': 'Bearer ' + access_token }
        }
        else
        {
            headers = auth.getAuthHeader();
        }
        axios.get(this.getBaseUrl + '/brewery/', { headers })
             .then((response) => {
                this.breweries = response.data.data.slice(0);                    
             })
             .catch((error) => {                    
                if(error.response.status == 401)
                {
                    console.log("error 401");
                    var new_access_token = auth.refreshToken();
                    this.loaded(new_access_token);
                }
            });
    }

Auth class

refreshToken(context) {
var token = 
{
  refresh_token: localStorage.getItem('refresh_token'),
  grant_type: 'refresh_token'
};
token = querystring.stringify(token);
axios.post(LOGIN_URL, token)
  .then((response) => {
    localStorage.removeItem('access_token');
    localStorage.setItem('access_token', response.data.access_token);
    this.checkLoggedIn();
    if(!this.isAdmin())
    {
      context.error = "You are not an admin user";
    }
    return response.data.access_token;
  })
  .catch(function (error) {
    if(error.response){
      if(error.response.status == 400)
      {
        console.log(error.response.data);
        context.error = error.response.data;
      }
    }
  })

}

1 个答案:

答案 0 :(得分:1)

这看起来像承诺链/结构问题。要在this.loaded调用完成后调用auth.refreshToken,您应该使refreshToken方法返回一个承诺。具体来说,它应该返回axios.post调用。 axios.post调用成功时实际执行此行return response.data.access_token;并解析令牌。现在,当您拨打auth.refreshToken时,您应该添加then块,如下所示:

auth.refreshToken().then((token) => { this.loaded(token) })

如果不以同步方式构造此代码,您将获得对this.loaded的多次调用,因为每个调用都会失败并带有陈旧的令牌......或者至少是一个未定义的令牌。