状态为200且数据为空时,Axios拦截器重试http请求

时间:2019-04-26 09:52:54

标签: node.js reactjs http axios

我正在短暂轮询一个端点,直到准备好一些数据为止,我想最多重试该请求10次。

  

当数据未准备好时,我收到一个200,其中包含一个空数组。

     

数据准备就绪后,我将收到一个非空数组200。

我使用以下库 https://github.com/axios/axios https://github.com/softonic/axios-retry

 try {

   const axiosInstance = axios.create();

   axiosInstance.interceptors.response.use((response) => {

     if (response.data.metrics.length === 0) {
       const error = new Error("Metrics Not Ready");
       return Promise.reject(error);

     }
     return response;
   }, (error) => {
     return Promise.reject(error);
   });

   axiosRetry(axiosInstance, {
     retries: 10,
     retryCondition: (error) => {
       console.log("RETRY CONDITION", error);
     },
   });

   const metrics = await axiosInstance(options);

 } catch (error) {
   console.log(error);
 }

我创建了一个axios拦截器,以检查数组的长度(如果0表示我抛出错误)。但是,axiosRetry并没有抓住这一点,在这一点上我想重试该请求。相反,它被捕获在try catch块中并结束。

1 个答案:

答案 0 :(得分:0)

您不需要axios-retry,只需要axios及其响应拦截器即可,并执行以下步骤:

  1. 检查数据是否为空。如果是,则抛出axios.Cancel错误。这将取消请求,调用错误处理程序而不是成功处理程序。
  2. 在错误处理程序中,如果我们没有超过最大重试次数(在您的情况下为10),则重新发送HTTP请求。
  3. 继续执行步骤1和2,直到获得数据或重试10次为止。

代码如下:

const axios = require('axios');

const MAX_RETRY = 10;
let currentRetry = 0;

function successHandler() {
  console.log('Data is Ready');
}

function errorHandler() {
  if (currentRetry < MAX_RETRY) {
    currentRetry++;
    console.log('Retrying...');
    sendWithRetry();
  } else {
    console.log('Retried several times but still failed');
  }
}

function sendWithRetry() {
  axios.get('http://example.com')
    .then(successHandler).catch(errorHandler);
}

axios.interceptors.response.use(function (response) {
  if (response.data.metrics.length) {
    throw new axios.Cancel('Operation canceled by the user.');
  } else {
    return response;
  }
}, function (error) {
  return Promise.reject(error);
});

sendWithRetry();

不幸的是,对于axios-retry,当响应状态为200 OK时,您无法重试HTTP请求,因为axios-retry使用axios.interceptors.response.use,但是对于“成功的响应”则不执行任何操作。

这是axios-retry的源文件es/index.js中的相应代码。您可以看到成功响应的拦截器是null

export default function axiosRetry(axios, defaultOptions) {
  axios.interceptors.request.use(config => {
    const currentState = getCurrentState(config);
    currentState.lastRequestTime = Date.now();
    return config;
  });

  axios.interceptors.response.use(null, error => {
    const config = error.config;

    // If we have no information to retry the request
    if (!config) {
      return Promise.reject(error);
    }
    ....