中断已经发出的ajax请求

场景

  • 用户在刚进入一个页面时,可能发送很多请求拿数据,这是如果用户快速切换至另一个页面或者组件,有的请求还没完成,而实际上这些请求已经没有用处,而如果此时刚好请求发生了错误触发了全局错误处理,可能会带来较差的用户体验。所以需要我们在合适的时候中断已经发出的请求。
  • 取消重复请求

本质

当一个ajax请求被发出时,XMLHttpRequest.abort()方法会终止该请求,它的readyState被置为0,status被置为0

axios中断请求

利用axios.CancelToke回调函数来中断请求。

  1. 创建请求池:当一个请求的method,url和params或者data全部重复时可认为是同一个请求,请求池以这个序列化后的字符串为参数,值为回调函数的cancel.
import axios from "axios"
import qs from 'qs';
import { InternalAxiosRequestConfig } from "axios"

let request = new Map()
// 添加请求
export const addRequest = (config: InternalAxiosRequestConfig): void => {
    const url = [
        config.method,
        config.url,
        qs.stringify(config.params),
        qs.stringify(config.data)
    ].join("&")

    config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
        if (!request.has(url)) { request.set(url, cancel) }
    })
}
  1. 移除请求
// 移除请求
export const removeRequest = (config: InternalAxiosRequestConfig) => {
    const url = [
        config.method,
        config.url,
        qs.stringify(config.params),
        qs.stringify(config.data)
    ].join("&")

    if (request.has(url)) {
        const cancel = request.get(url)
        cancel()
        request.delete(url)
    }
}
  1. 清空请求
// 清空请求
export const clearRequest = () => {
    for (const [url, cancel] of request) {
        cancel()
    }
    request.clear()
}
  1. 在请求拦截器中首先移除请求,之后将本次请求添加进请求池中
import axios from "axios";
import { addRequest, removeRequest } from "@/utils/cancelRequest"

const request = axios.create({
    baseURL: "XXX",
})

request.interceptors.request.use(config => {
    removeRequest(config)
    addRequest(config)
    return config
}, error => {
    console.log("request error:", error);
})

6.在响应拦截器中移除本次请求

request.interceptors.response.use(res => {
    removeRequest(res.config)
    return res.data
}, error => {
    return Promise.reject()
})

export default request

以上可实现中断重复需求的操作
7. 在beforeEach中执行clearRequest方法可在每次路由跳转时取消掉还没完成的请求

const router = createRouter({
    history: createWebHashHistory(),
    routes,
})

router.beforeEach((to, from, next) => {
    clearRequest()
    next()
})

export default router
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值