axios版本v0.22.0版本后可以使用fetch API 方式—— AbortController 取消请求。
官网说明:AbortController 接口的只读属性 signal 返回一个 AbortSignal 实例对象,该对象可以根据需要处理 DOM 请求通信,既可以建立通信,也可以终止通信。
我理解的在请求初始化之后会在options传入signal作为一个“标志”,从而将controller和请求串联起来,从而请求取消。
let controller;
const api = axios.create({
baseURL: '/api',
timeout: 30000,
responseType: 'json'
})
export function get(url, params = {}) {
try {
if (controller) { //第一次进入跳过
controller.abort()
}
controller = new AbortController()
const signal = controller.signal
return api({
url,
method: 'GET',
params,
signal
})
} catch (error) {
console.error('get:', error)
}
}
最后被中断的请求并不会消失而是会有个canceled的状态
全局封装
let urlHref = window.location.pathname // 当前url
let urlList = [] // url列表
let flag = false // 是否中断
let map = new Map()
export function callApi(url, config = {}) {
try {
c
if (window.location.pathname !== urlHref) { // 页面更换->初始值
urlHref = window.location.pathname
urlList = []
map = new Map()
}
urlList.push(url) // 将当前接口push
// 校验url算法
if (!urlList.length) { // 兜底
flag = false
}
for (let i in urlList) { // 遍历当前url列表,供map查询
if (map.has(url)) { // 如果当前url列表已存在当前的url路径,则将执行中断。此操作需删除掉当前的这一个url
map.delete(url)
urlList.pop()
flag = true
} else { // 不存在则将当前的url储存到map
map.set(urlList[i], i)
flag = false
}
}
// 是否中断
if (flag) { // 请求中断(相同接口)
if (controller) {
controller.abort() // 中断
}
controller = new AbortController()
return api({
url,
method: 'GET', // default get
...config,
signal: controller.signal // 中断"标志"
})
} else { // 无需中断(初次访问\多个不同接口)
controller = new AbortController()
return api({
url,
method: 'GET', // default get
...config,
signal: controller.signal
})
}
} catch (error) {
console.error('callApi:', error)
}
}