【HTTP】取消已发送的请求
场景
在页面中,可能会因为某些操作多次触发某个请求,如多次点击某按钮触发请求,实际上我们只需要最后一次请求的返回值,但是由于请求的耗时不一,请求未必会按发送的顺序返回,导致我们最终获取到的值 ≠ 最后一次发送请求的返回值。
根据项目经验,目前一共尝试过两种方法
1. 设置请求的唯一 id
2. 使用 axios 官方方法:AbortController
解决
1. 设置请求的唯一 id
为每个请求设置一个唯一 id,每触发一次请求,id+1,多次触发请求后,取值时根据请求 id 值来对应取值。
使用示例如下:
// 设置请求id初始值为0
sessionStorage.setItem('id', JSON.stringify(0))
/*** 发送请求* @param data 请求参数*/
function query(data) {loading.value = true// priceId加1,并存储在session里const priceId = JSON.parse(sessionStorage.getItem('id')) + 1sessionStorage.setItem('id', JSON.stringify(priceId))queryApi(data).then(res => {// 根据session中的priceId, 取最后一次请求的返回值if (priceId === JSON.parse(sessionStorage.getItem('id'))) {// 处理业务逻辑const { resultData } = res}}).catch(err => {// 业务处理逻辑}).finally(() => {loading.value = false})
}const url = '/query/abc'
function queryApi(paramsObj) {return httpInstance.post(url, paramsObj)
}
2. AbortController方法
AbortController 是 axios 官方提供的取消请求的 api,使用时注意:
1. 该 api 仅在 Axios 版本>=V0.22.0 时生效。
2. Axios 版本<V0.22.0 时请使用 CancelToken。
3. 允许取消一个或多个正在进行的请求,但如果请求已经成功响应则不能取消。
官网文档链接:取消请求 | Axios中文文档 | Axios中文网
使用示例如下:
// 用于存储当前的 AbortController 实例
let currentController = null
/*** 发送请求* @param data 请求参数*/
function query(data) {loading.value = true// 取消之前的请求if (currentController) {currentController.abort()currentController = null}const controller = new AbortController()currentController = controller //重置AbortControllerqueryApi(data, controller.signal).then(res => {const { resultData } = res// 业务处理逻辑.....loading.value = false}).catch(err => {if (err.name === 'CanceledError') {console.log('请求被取消', err.message)} else {console.error('请求失败', err)loading.value = false}})
}const url = '/query/abc'
function queryApi(paramsObj, signal) {return httpInstance.post(url, paramsObj, {signal: signal})
}