axios封装优化重复请求

前言

关于取消重复请求,最重要的是这么做的意义,而不在于代码的实现。其实,我觉得,绝大部分能够想到的应用场景,都可以通过防抖、节流方式实现,比如实时搜索,比如重复订单提交、比如上拉获取最新数据等。事实上,取消请求,请求也是会到达服务端的!只是发出后就不管了,不再接受服务端返回的数据。

场景:当用户连续点击或网络卡顿造成发送多个相同请求时
实现:当发送多个相同请求时,只会响应最后一次请求

原理

基于XMLHtppRequest.abort()

  1. 根据当前请求的请求方式、请求URL地址、请求参数生成一个唯一的 key
  2. 再为每个请求创建一个专属的CancelToken(取消token)
  3. 将 key 与 cancel 函数以键值对的形式存储起来
  4. 当出现重复请求时,使用 cancel 函数取消前面的请求
  5. 将取消的请求从集合中移除

具体代码

  1. 创建CancelRequest.js文件
export default class CancelRequest {
  pendings = []
  constructor(CancelToken) {
    this.CancelToken = CancelToken
  }
  getCancelToken(config) {
    const { CancelToken } = this
    return new CancelToken((cancel) => {
      const { url, method } = config
      const uKey = `{url}&{method}`
      this.pendings.push({ uKey, cancel })// config.data为请求参数
    })
  }
  removePending(config) {
    const { url, method } = config
    const { pendings } = this
    const uKey = `{url}&{method}`
    const findIndex = pendings.findIndex(p => p.uKey === uKey)
    const pendingsLen = pendings.length
    if (pendingsLen > 50) {
      // 如果pendings存储数量大于50,则释放缓存
      pendings.splice(0, pendingsLen - 2)
    }
    if (findIndex > -1) {
      pendings[findIndex].cancel()
      pendings.splice(findIndex, 1)
    }
  }
}

  1. 在axios中引入
// 主要代码
import CancelRequest from './CancelRequest'
const cancelRequest = new CancelRequest(axios.CancelToken)
// .....
service.interceptors.request.use(
    config => {
        /* -----------------------重复请求拦截------------------------- */
        // requestConfig?.skipCancelRequest 对需要重复请求的情况做处理skipCancelRequest为true跳过(用不到可删除)
        if (!requestConfig?.skipCancelRequest) {
          cancelRequest.removePending(config)
          config.cancelToken = cancelRequest.getCancelToken(config)
        }
        return config
    }
)


留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注