1. 使用 AbortController
AbortController
是Web API
的一部分,可以用来中止一个或多个 fetch 请求- 虽然 Axios 默认
不支持
直接使用 AbortController,但你可以通过传递 AbortController 的signal
属性到Axios请求
中来实现这一功能 - 对于循环请求,你需要
为每个请求创建一个新的 AbortController 实例
,并在合适的时机调用abort
方法。
js
const controller = new AbortController();
const { signal } = controller;
// 在你的请求中传递 signal
axios.get('/your-endpoint', { signal }).then(response => {
// 处理响应
});
// 当需要中止请求时
controller.abort();
实例:如果有相同请求,先中断前一个
js
const api = axios.create({
baseURL: import.meta.env.VITE_APP_API_BASEURL,
timeout: 1000 * 60,
})
const pendingMap = new Map() // abort 取消重复请求
function removePending(config: AxiosRequestConfig) {
const key = `${config.method}:${config.url}:${JSON.stringify(filterNullUndefined(config.params || config.data))}`
const abort = pendingMap.get(key)
if (abort) {
abort('cancel')
pendingMap.delete(key)
}
}
// axios实例拦截请求
api.interceptors.request.use(
(config) => {
// 如果有相同请求,先中断前一个
removePending(config)
const abortController = new AbortController()
config.signal = abortController.signal
pendingMap.set(
`${config.method}:${config.url}:${JSON.stringify(filterNullUndefined(config.params || config.data))}`,
() => abortController.abort('cancel'),
)
return config
},
(error) => {
return Promise.reject(error)
},
)
2. 使用 Axios 的 CancelToken
Axios
提供了CancelToken
功能,可以用来取消请求。你可以创建一个CancelToken 实例
,并在请求中传递它- 对于循环请求,你同样需要
为每个请求创建一个新的 CancelToken 实例
,并保存每个请求的取消函数
js
import axios from 'axios'
const CancelToken = axios.CancelToken
let cancel
axios.get('/your-endpoint', {
cancelToken: new CancelToken((c) => {
// 保存取消函数
cancel = c
}),
}).then((response) => {
// 处理响应
})
// 当你需要取消请求时
cancel()
实例:离开页面前中断循环请求
js
const cancel = reactive<any>({})
// 单个请求体,i为索引
function singleChunk(i: number) {
const dId = dataId.value
const p = () => {
return new Promise((resolve, reject) => {
chunkDownload({
id: dId,
chunk: i + 1,
}, {
cancelToken: new CancelToken((c) => {
// 保存取消函数
cancel[i + 1] = c
}),
}).then((info) => {
// ....
})
.catch((err) => {
reject(err)
})
})
}
return p
}
// ......................................
// 页面销毁前
onBeforeUnmount(() => {
// 终止请求
for (const key in cancel) {
if (typeof (cancel[key] === 'function')) {
cancel[key]()
}
}
})