Axios请求拦截器等待直到ajax调用完成 [英] Axios Request Interceptor wait until ajax call finishes

查看:655
本文介绍了Axios请求拦截器等待直到ajax调用完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用于axios调用的请求拦截器.它检查我的jwt令牌,并在必要时调用刷新.

I have an request interceptor for axios calls. It checks my jwt token and call for refresh if necessary.

axios.interceptors.request.use((config) =>{

    const state = store.getState(); // get renewed state
    const time = Math.floor( new Date().getTime() / 1000 );

    if( 
        ! state.app.jwtRefreshOnRequest 
        && time >= state.jwt.expires - 120
        && state.jwt.refresh_before > time
    ){ // expiring in 2 min. refresh    

        //dispatch({type: 'JWT_REFRESH_REQUEST'});
        axios.get( API_BASE_URL + '/auth/refresh')
            .then(function(response){
                // dispatch({type: 'JWT_REFRESH_SUCCESS', payload: response.data});
                axios(config).then(resolve, reject);
            })
            .catch(function(err){               
                reject(err);
        });

    }       

    return config;
}); 

此代码正确调用刷新并保存新令牌,但原始调用在拦截器请求完成之前不成立,因此使用过期的令牌.

This code calls the refresh correctly and saves the new token but the original call doesn't holds until the interceptor request is done, so the expired token is used.

所以,我想我需要从拦截器进行同步调用.

So, I guess I need to make synchronous call from interceptor.

推荐答案

避免对HTTP请求进行同步调用,因为它们只会使您的应用程序挂起.

Avoid synchronous calls for HTTP requests, as they just make your application hang.

这里您需要做的是使调用代码异步-与回调,promise或async相关的一般规则是,一旦异步,一切都必须是异步的.

What you need to do here is make the calling code asynchronous - the general rule with anything callback, promise or async related is that once you are async everything needs to be async.

在这里,axios.get返回一个Promise-一个跟踪异步HTTP请求并在完成后解析的对象.您需要返回该值,而不是config.

Here, axios.get returns a Promise - an object that keeps track of the asynchronous HTTP request and resolves once it has finished. You need to return that, rather than the config.

我们通过返回一个新的Promise来做到这一点-如果需要新令牌的HTTP请求,它将等待它,如果没有,它可以立即resolve.

We do that by returning a new Promise - if an HTTP request for a new token is required it waits for it, if no it can resolve immediately.

axios.interceptors.request.use(config =>
    new Promise((resolve, reject) => {
        // ... your code ...

        axios.get( API_BASE_URL + '/auth/refresh')
            .then(response => {
                // Get your config from the response
                const newConfig = getConfigFromResponse(response);

                // Resolve the promise
                resolve(newConfig);
            }, reject);

        // Or when you don't need an HTTP request just resolve
        resolve(config);
    })
}); 

只要您看到then就是在处理Promise,一旦您一切,都需要返回Promise.

Whenever you see that then you're dealing with Promise, and once you are everything needs to return a Promise.

如果您可以使用async/await-这是现代的浏览器支持的新关键字,并且可以在需要支持旧版用户的情况下进行转换,则 更加容易.有了这些,您就可以将Promise调用与await关键字内联.

This is much easier if you can use async/await - new keywords supported by modern browsers and transpilable if you need to support legacy users. With these you can just put the Promise call inline with the await keyword.

axios.interceptors.request.use(async config =>

    // ... your code ...

    if(/* We need to get the async token */) {
        const response = await axios.get( API_BASE_URL + '/auth/refresh');
        config = getConfigFromResponse(response);
    }

    return config;
}); 

这篇关于Axios请求拦截器等待直到ajax调用完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆