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

    正文概述 掘金(有刃有鱼阮小六)   2021-02-21   618

    axios取消重复请求CancelToken可以让同一个请求遭到用户多次触发时,只返回最近的一次请求结果,而取消之前的请求

    在业务生产过程中,这个优化可以增强用户体验,减少不必要的数据接收和页面渲染。

    使用它很简单,我们只要对axios进行一层封装:

    // 封装axios请求
    import axios from 'axios'
    import config from '@/config'
    import errorHandle from './errorHandle'
    const CancelToken = axios.CancelToken
    
    class HttpRequest {
      constructor(baseURL) {
        this.baseURL = baseURL
        this.pending = {}
      }
      // 获取预设的配置
      getInsideConfig() {
        return {
          baseURL: this.baseURL,
          headers: { 'Content-Type': 'application/json;charset=utf-8' },
          timeout: 10000,
          withCredentials: false // 跨域时是否使用凭证,默认false
        }
      }
      // 取请求url、method、params、data等组成key,标识这次请求
      getPendingKey(config) {
        return [
          config.url,
          config.method,
          JSON.stringify(config.params),
          JSON.stringify(config.data)
        ].join('&')
      }
      // 移除请求pending
      removePending(key, isRequest = false) {
        if (this.pending[key] && isRequest) {
          this.pending[key]('取消重复请求')
        }
        delete this.pending[key]
      }
      // 拦截处理
      interceptors(instance) {
        // 添加请求拦截器
        instance.interceptors.request.use(
          config => {
            // 1、取请求标识key
            // 2、移除上一次该请求标识(如果有,则调用cancelToken取消上次请求)
            // 3、给这次请求增加cancelToken备用(如果后续有重复请求则调用)
            const key = this.getPendingKey(config)
            this.removePending(key, true)
            config.cancelToken = new CancelToken(cancel => {
              this.pending[key] = cancel
            })
            return config
          },
          error => {
            // 对请求错误做些什么
            errorHandle(error)
            return Promise.reject(error)
          }
        )
    
        // 添加响应拦截器
        instance.interceptors.response.use(
          response => {
            // 请求返回结果,移除pending
            const key = this.getPendingKey(response.config)
            this.removePending(key)
            if (response.status === 200) {
              return Promise.resolve(response.data)
            } else {
              return Promise.reject(response)
            }
          },
          error => {
            // 对响应错误做些什么
            errorHandle(error)
            return Promise.reject(error)
          }
        )
      }
      // 发送请求
      request(config) {
        const instance = axios.create()
        const newOptions = Object.assign(this.getInsideConfig(), config)
        this.interceptors(instance)
        return instance(newOptions)
      }
    
      // 语法糖,get请求
      get(url, config) {
        const options = Object.assign(
          {
            url,
            method: 'get'
          },
          config
        )
        return this.request(options)
      }
      // 语法糖,post请求
      post(url, data, config) {
        const options = Object.assign(
          {
            url,
            data,
            method: 'post'
          },
          config
        )
        return this.request(options)
      }
      // 语法糖,put请求
      put(url, data, config) {
        const options = Object.assign(
          {
            url,
            data,
            method: 'put'
          },
          config
        )
        return this.request(options)
      }
      // 语法糖,delete请求
      delete(url, config) {
        const options = Object.assign(
          {
            url,
            method: 'delete'
          },
          config
        )
        return this.request(options)
      }
    }
    
    HttpRequest.prototype.all = axios.all
    HttpRequest.prototype.spread = axios.spread
    
    export default new HttpRequest(config.baseURL)
    
    

    这样在我们短时间内多次触发同一个请求时,在网络较慢,前一个请求还在pendding状态下,axios就可以取消掉前一次的请求

    axios取消重复请求不会阻止请求到服务器

    但是该做法会潜藏一个问题,就是这些被取消的请求,还是会发给后端。这个问题导致的后果就是,比如我点击按钮插入数据,连续点击5次,虽然重复的被取消了,但是在后端依然接受到这5次请求,并执行了5次插入数据。

    我在后端接口中埋了打印点,当被请求时触发:

    axios取消重复请求不会阻止请求到服务器

    所以以前刚开始理解的axios通过CancelToken取消重复请求,会把之前的取消掉,请求不会发出去给后端,这是错误的理解

    只要点击了按钮触发事件,请求就发出去了,尽管可以取消重复请求,只要网络还在连接,后端还是会一一收到所有的请求,该查库的查库,该创建的创建,只是重复请求返回的数据被前端取消了而已,前端只接受最后一次数据,渲染一次页面。

    针对该问题,可以有多种优化方式,比如后端可以做控制,对于重复创建等操作进行限制,而在前端可以在按钮点击后显示loading状态等,以限制用户重复点击触发。


    起源地下载网 » axios取消重复请求不会阻止请求到服务器

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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