How do I cancel duplicate requests in Axios? In this article, Arbogo explains how to cancel repeated requests in Axios and how CancelToken works. This article shows how request retry can be implemented in Axios via interceptors or adapters. So why request retry? This is because in some cases, such as when a request times out, we want to be able to automatically re-initiate the request and retry the operation to complete the corresponding operation.

If you’re not familiar with Axios’s interceptors and adapters, I recommend reading the 77.9K Axios project for lessons to learn. Next, we’ll show you how to implement a request retry scheme using interceptors.

The interceptor implements the request retry scheme

Axios is an HTTP client based on promises, whereas the HTTP protocol is based on requests and responses:

So Axios provides a request interceptor and a response interceptor to handle requests and responses, respectively, as follows:

  • Request interceptor: This class of interceptors is used to uniformly perform certain operations before a request is sent, such as adding a token field to the request header.
  • Response interceptor: This type of interceptor is used to perform certain operations after receiving a response from the server. For example, if the response status code is 401, the system automatically jumps to the login page.

Set in the Axios interceptor is very simple, through Axios. Interceptors. Request and Axios interceptors. The response object provides the use method, can be set respectively request interceptor and the interceptor:

export interface AxiosInstance {
  interceptors: {
    request: AxiosInterceptorManager<AxiosRequestConfig>;
    response: AxiosInterceptorManager<AxiosResponse>;
  };
}

export interfaceAxiosInterceptorManager<V> { use(onFulfilled? :(value: V) = > V | Promise<V>, onRejected? :(error: any) = > any) :number;
  eject(id: number) :void;
}
Copy the code

For the request retry function, we want the user to be able to set not only the number of retries, but also the retry delay. When a request fails, Axios retries the request if the request’s configuration object is configured with retries. To enable request retries globally, let’s implement request retries on the response interceptor as follows:

axios.interceptors.response.use(null.(err) = > {
  let config = err.config;
  if(! config || ! config.retryTimes)return Promise.reject(err);
  const { __retryCount = 0, retryDelay = 300, retryTimes } = config;
  // Set the retry count on the request object
  config.__retryCount = __retryCount;
  // Determine whether the number of retries has exceeded
  if (__retryCount >= retryTimes) {
    return Promise.reject(err);
  }
  // Increase the number of retries
  config.__retryCount++;
  // delay processing
  const delay = new Promise((resolve) = > {
    setTimeout(() = > {
      resolve();
    }, retryDelay);
  });
  // Re-initiate the request
  return delay.then(function () {
    return axios(config);
  });
});
Copy the code

The above code is not complicated, and the corresponding processing flow is shown in the figure below:

After explaining how to use an interceptor to implement request retry, here’s how the adapter implements request retry.

Pay attention to “the road of full stack Repair fairy” to read the original 4 free e-books of Po Ge (total download 30,000 +) and more than 50 TS series tutorials.

The adapter implements the request retry scheme

Axios introduces adapters that allow it to support both browser and Node.js environments. For the browser environment, it sends HTTP requests by encapsulating the XMLHttpRequest API, and for the Node.js environment, it sends HTTP requests by encapsulating the built-in HTTP and HTTPS modules of Node.js.

How does Axios cache request data? In this article, Arbogo shows how to enhance the default Axios adapter to cache request data. Similarly, we can enhance the default Axios adapter to enable request retries.

Before we look at how to enhance the default adapter, let’s take a look at Axios’s built-in xhrAdapter, which is defined in the lib/ Adapters /xhr.js file:

// lib/adapters/xhr.js
module.exports = function xhrAdapter(config) {
  return new Promise(function dispatchXhrRequest(resolve, reject) {
    var requestData = config.data;
    var requestHeaders = config.headers;

    var request = new XMLHttpRequest();
    // Omit most of the code
    var fullPath = buildFullPath(config.baseURL, config.url);
    request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
    // Set the request timeout in MS
    request.timeout = config.timeout;

    // Listen for ready state
    request.onreadystatechange = function handleLoad() {... }// Send the request
    request.send(requestData);
  });
};
Copy the code

Obviously the xhrAdapter adapter is a function object that takes a Config parameter and returns a Promise object. Within the xhrAdapter adapter, you end up using the XMLHttpRequest API to send HTTP requests. To enable request retry, we can consider enhancing the xhrAdapter capabilities with higher-order functions.

2.1 Define the retryAdapterEnhancer function

To give users more flexibility in controlling the retry function, we have defined a retryAdapterEnhancer function that supports two parameters:

  • Adapter: A pre-enhanced Axios adapter object;
  • Options: Cache configuration object. This object supports two properties for configuring different functions:
    • Times: indicates the number of global request retries.
    • Delay: indicates the delay of global Settings, in ms.

Now that we know the parameters of the retryAdapterEnhancer function, let’s look at the implementation:

function retryAdapterEnhancer(adapter, options) {
  const { times = 0, delay = 300 } = options;

  return async (config) => {
    const { retryTimes = times, retryDelay = delay } = config;
    let __retryCount = 0;
    const request = async() = > {try {
        return await adapter(config);
      } catch (err) {
        // Determine whether to retry
        if(! retryTimes || __retryCount >= retryTimes) {return Promise.reject(err);
        }
        __retryCount++; // Increase the number of retries
        // delay processing
        const delay = new Promise((resolve) = > {
          setTimeout(() = > {
            resolve();
          }, retryDelay);
         });
         // Re-initiate the request
         return delay.then(() = > {
           returnrequest(); }); }};return request();
  };
}
Copy the code

The above code is not complicated, and the core processing logic is shown below:

2.2 Using the retryAdapterEnhancer function

2.2.1 Create Axios objects and configure Adapter options
const http = axios.create({
  baseURL: "http://localhost:3000/".adapter: retryAdapterEnhancer(axios.defaults.adapter, {
    retryDelay: 1000,})});Copy the code
2.2.2 Sending requests using HTTP Objects
// The request fails
function requestWithoutRetry() {
  http.get("/users");
}

// The request failed and retry
function requestWithRetry() {
  http.get("/users", { retryTimes: 2 });
}
Copy the code

Ok, we’ve covered how to implement Axios request retry capabilities by enhancing the xhrAdapter adapter. Because the complete sample code content is more, Po brother will not put the specific code. If you are interested, please visit the following address to browse the sample code.

The complete sample code: gist.github.com/semlinker/9…

Here’s a look at the results of the Axios request retry example:

Third, summary

This article showed you how to implement request retries in Axios, and you can easily extend request retries based on the retryAdapterEnhancer function or response interceptor defined in this article. Axios is an excellent open source project with a lot to learn from. If you are interested in the design and implementation of Axios’s internal HTTP interceptor, the design and implementation of HTTP adapters, and how to defend against CSRF attacks, you can read what the 77.9K Axios project can learn from this article.

Pay attention to “the road of full stack Repair fairy” read 4 free e-books of Po Ge original (total download 30,000 +) and 11 advanced series of Vue 3 tutorials. If you want to learn TS/Vue 3.0 together, you can add Semlinker on wechat.

Iv. Reference resources

  • Github – axios-extensions
  • How does Axios cancel duplicate requests?
  • How does Axios cache request data?
  • What can be learned from the 77.9K Axios project