最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • axios 撤销请求

    正文概述 掘金(乘法口诀)   2021-02-20   620

    使用场景

    1. tab 切换时刷新列表数据,如果使用的是同一个 dom 展示数据,当请求有延时,可能会导致两个 tab 数据错乱
    2. 导出文件或下载文件时,想中断导出或下载

    注意事项

    前端主动撤销请求依旧会触发服务端逻辑,会占用服务端资源,一般按钮触发的请求用限制点击来处理

    具体使用

    主要思路:使用变量存储当前状态为请求状态的请求,在请求拦截中收集请求并判断是否有已有相同的正在请求过程中的请求,在响应拦截中移除该请求保证变量中存储的请求状态都为请求中

    1.定义变量和取消方法
    const httpPending = [] // 用于存储每个ajax请求的取消函数和ajax标识
    
    // 取消请求方法
    const cancelHttp = (name, config = {}) => {
        httpPending.forEach((e, i) => {
            if (e.n === name || e.n === config.xhrName) {
                // 当前请求在数组中存在时执行函数体
                e.f("我撤销了请求") // 执行取消操作
                httpPending.splice(i, 1) // 把这条记录从数组中移除
            }
        })
    }
    
    2.http 封装
    export default class Http {
        static async request(method, url, opts = {}) {
            let params = {
                xhrName: (opts && opts.name) || "",
                method,
                url: uri,
            }
            return axios(params)
        }
        static post(url, opts) {
            return this.request("POST", url, opts)
        }
    }
    
    3.请求拦截
    axios.interceptors.request.use(
        (config) => {
            // 取消上一次未完成的相同请求,注意项目中是否存在风险
            cancelHttp(null, config)
            config.cancelToken = new CancelToken((c) => {
                if (config.xhrName) {
                    httpPending.push({
                        n: config.xhrName,
                        u: `${config.url}&${config.method}`,
                        f: c,
                    })
                }
            })
    
            return config
        },
        (error) => Promise.reject(error)
    )
    
    4.响应拦截
    axios.interceptors.response.use((res) => {
        cancelHttp(null, res.config) // 响应成功把已经完成的请求从 httpPending 中移除
    })
    
    5.通过 name 标识该请求是否能被撤销
    export const httpRequest = (params) =>
        Http.post("/api", { name: "httpRequest", body: params })
    

    实现原理

    1.首先明确

    axios 是对 XMLHttpRequest 的封装,撤销请求时,最终使用 XMLHttpRequest 的 abort()方法

    2.axios 内部实现

    CancelToken 模块暴露了一个 promise 执行撤销的时候会执行这个 promise 的 resolve

    function CancelToken(executor) {
        if (typeof executor !== "function") {
            throw new TypeError("executor must be a function.")
        }
    
        var resolvePromise
        this.promise = new Promise(function promiseExecutor(resolve) {
            resolvePromise = resolve
        })
    
        var token = this
        executor(function cancel(message) {
            if (token.reason) {
                // Cancellation has already been requested
                return
            }
    
            token.reason = new Cancel(message)
            resolvePromise(token.reason)
        })
    }
    

    resolve 执行之后进入 then 里面的 function 执行最终的 abort()

    config.cancelToken.promise.then(function onCanceled(cancel) {
        if (!request) {
            return
        }
    
        request.abort()
        reject(cancel)
        // Clean up request
        request = null
    })
    

    起源地下载网 » axios 撤销请求

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元