Discussion on Axios scheme for removing duplicate requests
- 2021-11-13 06:19:40
- OfStack
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()
})