Skip to content

axios取消请求大有用处

一、问题举例

  • 表格分页功能中,快速点击下一页,若前一次请求的时间比后一次长,最后表格会渲染前一次的数据
  • 远程搜索输入框,快速输入文字,比如“张三”,最后查询的结果可能会是“张”的搜索结果
  • 不断切换菜单,可能会在B页面出现A页面的接口异常提示

二、常见解决方案

  • 防抖、截流
  • 扩大loading的覆盖面

三、axios取消请求解决方案

以上方案都是以限制用户操作为手段,牺牲了一部分用户体验。下面介绍如何使用axios取消请求功能来解决此问题。

  • 封装axios时,拦截get请求,将请求存入httpRequestList
js
let httpRequestList = []
axiosInstance.interceptors.request.use(
    async function (config) {
        if ("get" == config.method.toLowerCase()) {
            //将所有get请求加入到取消列表中,在cancelRequest进行判断
            config.cancelToken = new axios.CancelToken(function executor(cancel) {
                config.cancel = cancel
                httpRequestList.push(config)
            })
        }
    }
)
  • 封装全局的取消请求的方法,cancelId重点!
js
function cancelRequest(cancelId) {
    if(!cancelId) return
    let cancelIndex = httpRequestList.findIndex(item => item.cancelId == cancelId)
    if(cancelIndex < 0) return
    httpRequestList[cancelIndex].cancel("#change-cancel#"+item.url)
    httpRequestList.splice(cancelIndex, 1)
}

//将此方法挂载到Vue
Vue.prototype.$cancelRequest = cancelRequest
  • 具体应用时,使用cancelId取消请求,并在请求时传入
js
this.$cancelRequest(this.cancelId)
await this.$axios.get(url, {
    params,
    cancelId: this.cancelId
});

TIP

axios取消请求不会中断服务端的处理过程,并不会降低服务端的资源消耗,只是会提前结束请求。