请求封装,请求频繁取消上一次请求,封装失败重试
js
import axios from 'axios'
const request = axios.create({
timeout: 5000,
data: {},
params: {},
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
// 声明一个数组用于存储每个ajax 请求标志, 重复请求时取消上一次请求
const pendingMap = new Map()
const CancelToken = axios.CancelToken
const removePending = ever => {
// 删除该请求在 pending 中的记录
let key = `${ever.url}&${JSON.stringify(ever.params)}&${JSON.stringify(ever.data)}&${ever.method}`
if (pendingMap.has(key)) {
pendingMap.get(key)()
pendingMap.delete(key)
}
}
// 请求拦截
request.interceptors.request.use(
config => {
// 在ajax 发送前,取消该接口的上一次请求
removePending(config)
config.cancelToken = new CancelToken(cancel => {
// 构造 ajax 请求标志
const url = `${config.url}&${JSON.stringify(config.params)}&${JSON.stringify(config.data)}&${config.method}`
pendingMap.set(url, cancel)
})
return config
},
)
// 重试次数
const retry = 2
// 重试延迟
const retryDelay = 500
// 返回拦截
request.interceptors.response.use(
response => {
// 请求成功之后,把请求标志从pending 队列中删除
removePending(response.config)
return response.data
},
err => {
// ! 请求错误重试
const config = err.config
// 没有请求次数,或者重试次数结束则直接返回错误
if (!config || !retry || config.retryCount >= retry) {
return Promise.reject(err)
}
config.retryCount = config.retryCount || 0
// console.log(`第${config.retryCount + 1}次重试`)
config.retryCount += 1
const backoff = new Promise(resolve => {
setTimeout(() => {
resolve()
}, retryDelay)
})
return backoff.then(() => {
return request(config)
})
}
)
export default request