Discussion on Axios scheme for removing duplicate requests

  • 2021-11-13 06:19:40
  • OfStack

Directory 1. Cancel 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()
  })

Related articles: