Discussion on Axios scheme for removing duplicate requests


2. Clean up all requests

This scheme has two main functions

1. After the request is issued, the subsequent repeated requests will be cancelled and not processed, waiting for the first request to be completed. 2. After the route jump, the previous page did not complete the request cleanup.

1. Cancel duplicate requests

Pre-knowledge:

1. For the cancellation method officially provided by 1. axios, please refer to the relevant documents: CancelToken 2. js Map related concepts 3. Secure query string parsing and string decomposition library qs, which is similar to JSON provided by js

In order to simplify parameter processing, only post requests are considered in this scheme, that is, if method, url and data are the same, they are regarded as duplicate requests

// axios.js
const pending = new Map()
/**
 *  Add request
 * @param {Object} config
 **/
const addPending = (config) => {
  const url = [
    config.method,
    config.url,
    qs.stringify(config.data)
  ].join('&')
  if (pending.has(url)) { //  If  pending  Cancel subsequent requests if the current request exists in
    config.cancelToken = new axios.CancelToken(cancel => cancel(` Duplicate requests are actively intercepted : ${url}`))
  } else { //  If  pending  If the current request does not exist in, add it
    config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
      pending.set(url, cancel)
    })
  }
}
/**
 *  Remove request
 * @param {Object} config
 */
const removePending = (config) => {
  const url = [
    config.method,
    config.url.replace(config.baseURL, ''), //  Response url The domain name will be added, which needs to be removed from the request URL Keep 1 To
    qs.stringify(JSON.parse(config.data)) //  Need and request Parameter structure preservation of 1 To, request Is an object in, response Is a string in
  ].join('&')
  if (pending.has(url)) { //  If in  pending  The current request identity exists in the, cancel the current request, and remove the
    pending.delete(url)
  }
}

/* axios Global request parameter settings, request interceptor  */
axios.interceptors.request.use(
  config => {
    addPending(config) //  Add the current request to the  pending  Medium
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
//  Response interceptor is exception handling
axios.interceptors.response.use(
  response => {
    removePending(response.config) //  After the request ends, remove this request
    return response
  },
  err => {
    if (err && err.config) {
      removePending(err.config) //  After the request ends, remove this request
    }
    return Promise.resolve(err.response)
  }
)

2. Clean up all requests

// axios.js
/**
 *  Empty  pending  Request in (called when the route jumps)
 */
export const clearPending = () => {
  for (const [url, cancel] of pending) {
    cancel(url)
  }
  pending.clear()
}
// router.js
router.beforeEach((to, from, next) => {
  //  Routing jump, clearing all requests
  clearPending()
  })