The introduction

Now that YOU’ve seen how axios interceptors are used and how they can be wrapped up in the last article, let’s take a look at how interceptors handle situations where response times are too long and the number of requests is too high.

A method to cancel a request

Axios uses the internally provided CancelToken to cancel the request

Example 1: Create the Cancel token with the canceltoken. source factory method, like this

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // Processing error}}); axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// Cancel the request (the message argument is optional)
source.cancel('Operation canceled by the user.');
Copy the code

Example 2: By passing an executor function toCancelTokenConstructor to create the Cancel token:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // The executor function takes a cancel function as an argumentcancel = c; })});// cancel the request
cancel();
Copy the code

As you can see, these are all cancel tokens created in a single request. In practice, we need to process all requests. How do we implement cancellation in the interceptor

Cancels repeated requests in interceptors

import axios from 'axios'
import baseURL from './config'
import qs from 'qs'

const pendingRequest = new Map(a);// Request object
const CancelToken = axios.CancelToken;

axios.defaults.timeout = 30000
axios.defaults.baseURL = baseURL.target

// Add request interceptor
axios.interceptors.request.use(function(config) {
  // What to do before sending the request
  config.headers = {
      'content-type': 'application/json'.'token': getToken()
  }
  // Get the request key
  let requestKey = getReqKey(config);

  // Determine if the request is repeated
  if (pendingRequest.has(requestKey)) { // The request is repeated
    removeReqKey(requestKey); / / cancel
  }else{
    / / set cancelToken
    config.cancelToken = new CancelToken(function executor(cancel) {
      pendingRequest.set(requestKey, cancel); / / set})}return config;
}, function (error) {
  // Request error
  return Promise.reject(error);
});

// Add a response interceptor
axios.interceptors.response.use(function (response) {
  Delete the requestKey from the request object
  let requestKey = getReqKey(response.config);
  removeReqKey(requestKey);

  // Do something with the returned data such as state interception
  if(response.data.status ! = =200) {
      Toast({
        message: response.data.message,
        type: 'warning'.duration: 1000
      })
      return
    }
    
  // No problem
  return response.data;
}, function (error) {
  let requestKey = getReqKey(error.config);
  removeReqKey(requestKey);
  
  // Response error
  return Promise.reject(error);
});

// Get the request key
function getReqKey(config) {
  // Request mode, request address, request parameters to generate a string to determine whether to repeat the request
  const { method, url, params, data } = config; // Deconstruct the parameters
  // GET ---> params POST ---> data
  const requestKey =  [ method, url, qs.stringify(params), qs.stringify(data)].join('&');
  return requestKey;
}

// Cancel duplicate requests
function removeReqKey(key) {
  const cancelToken = pendingRequest.get(key);
  cancelToken(key); // Cancel the previously sent request
  pendingRequest.delete(key); Delete the requestKey from the request object
}
Copy the code

conclusion

The above is the processing of repeated requests. If you are not clear about interceptors, you can read the previous article. If you have any questions, please put forward corrections.