首页 > 解决方案 > Axios 承诺解决飞行前请求响应,这使得关联的 GET 与应用程序的其余部分无序执行

问题描述

再会,

我正在开发一个使用 React-Redux (with Thunk) 和 Axios 的 React 应用程序。

我有一个我调度的操作,它进行了经过身份验证的 API 调用。由于我在跨域请求上有授权标头,因此有一个飞行前请求。

我遇到的问题是,一旦飞行前请求返回而不是关联的 GET 请求返回时,Axios 似乎正在运行 .then() 代码。这会导致在 API GET 请求的结果返回之前,Reducer 函数更新状态。

我添加了一些 console.logs 来提供更多细节来说明问题。如您所见,飞行前请求是在第一个条目中发送的。.then 执行一个飞行前请求返回 200 的操作。然后该操作触发,reducer 更新状态。我的应用程序通过重新渲染连接到 Redux 的容器来响应。子组件随后也会更新。然后 GET 请求完成并返回 200。此时没有进一步的事情发生,因为 reducer 已经在前面提到的 .then() 中更新。

动作代码如下所示。我没有粘贴所有其他代码,因为有许多文件并且它们相对较大。如果需要,我也可以包括这些。 网络选项卡详细信息

export const updatePlotDataInit = (datasetName, tableName, xFieldName, 
    yFieldName, chartId, chartType, plotId, newDomainStartDbIndex, newDomainEndDbIndex) => {
        console.log('[actions/plot.js.js] - [updatePlotDataInit] - [start of function]');
    return dispatch => {
        dispatch(updatePlotDataStart());
        console.log('[actions/plot.js.js] - [updatePlotDataInit] - [just before api request]');
        instance.get( // custom axios instance with extra auth header used here
            `/v1/datasets/${datasetName}/tables/${tableName}/fields/data?xField=${xFieldName}&yField=${yFieldName}&chartType=${chartType}&domainStart=${newDomainStartDbIndex}&domainEnd=${newDomainEndDbIndex}`
            )
            .then(response => {
                console.log('[actions/plot.js.js] - [updatePlotDataInit] - [in .then before updatePlotDataSuccess]');
                // dispatch redux action for success case
                const currentLevel = response.data.metaData.current_level 
                const data = response.data.queryData.data //schema is available too
                //datasetId, tableId, xFieldId, xField, yFieldId, yField, chartId, plotIdVal, currentLevel, data
                dispatch( updatePlotDataSuccess( plotId, currentLevel, data ) );
                // console.log(response);
                console.log('[actions/plot.js.js] - [updatePlotDataInit] - [in .then after updatePlotDataSuccess]')
            })
            .catch(error => {
                console.log(error);

            // dispatch redux action for failure case
            dispatch(updatePlotDataFail(error));
            })
    }
};

我不完全确定,但似乎 Axios 认为成功的飞行前响应适合解决 promsie,因此 .then 被执行。

这似乎是这样吗?如果是这样,我将如何强制 Axios 在解决承诺之前等待 GET/POST/PUT/etc 成功?

任何帮助表示赞赏。

标签: reactjsreact-reduxaxioses6-promiseredux-thunk

解决方案


我知道这是很久以前的事了,但我认为它可能对其他发现这个问题与他们的问题相似但没有答案的人有用......

对我来说,这只是因为编码粗心:D,这是我的响应接收器,我在 Promise.resolve(axios(originalRequest)); 之前错过了“返回”。我通过添加 return 解决了它:

AxiosInstance.interceptors.response.use(
    (response) => {
        return response;
    },
    function (error) {
        const originalRequest = error.config;
        let refreshToken = localStorage.getItem("refreshToken");
        if (
            refreshToken &&
            error.response.status === 401 &&
            !originalRequest._retry
        ) {
            originalRequest._retry = true;
            return axios
                .post(apiUrl + `auth/refreshtoken`, { refreshToken: refreshToken })
                .then((res) => {            
                    if (res.status === 200) {
                        localStorage.setItem("accessToken", res.data.accessToken);
                        console.log("Access token refreshed!" + res.data.accessToken);       
                        originalRequest.headers.Authorization = 'Bearer ' + res.data.accessToken;
         //*************** I just return promise.resolve *****************//
                        return Promise.resolve(axios(originalRequest)); 
                    }
                }).catch((error) => {
                    console.log(error);
                });

        }
        return Promise.reject(error);
    }

推荐阅读