Interface request throttling limit

1. The meaning of throttling

 1. When the front-end calls the interface, sometimes the back-end interface will be called multiple times continuously through the interface, which will increase the response load of the back-end and occupy the bandwidth for outgoing service data, resulting in a waste of resources.

2. Implementation method

1. The general implementation uses the same URL, request method, and request parameters as the cache key. Each time the interface is requested, the key is stored in the cache object. After the interface response is completed, the key is removed from the cache object.

2. When sending a request, use the key to obtain the value from the cache object. If a value is obtained, the request has been requested but has not been completed, and the request will be interrupted.

3. Implement the code

1. Create new throttleHttp.js

// 新建map用于存放正在执行的请求
const pendingRequest = new Map()

class throttleHttp {
  constructor(originalAxios) {
    this.originalAxios = originalAxios
  }

  // generateReqKey:用于根据当前请求的信息,生成请求Key存放到map中作为当前请求的键;
  generateReqKey(config) {
    let { method, url, params, data } = config
    if (typeof params === 'string') {
      params = JSON.parse(params)
    }
    if (typeof data === 'string') {
      data = JSON.parse(data)
    }
    // return [method, url.replace(config.baseURL, ''), JSON.stringify(params), JSON.stringify(data)].join('&')
    return [method, url.replace(`${config.baseURL}/`, ''), JSON.stringify(params), JSON.stringify(data)].join('&')
  }

  // addPendingRequest:用于把当前请求信息添加到pendingRequest对象中
  addPendingRequest(config) {
    const requestKey = this.generateReqKey(config)
    // 这下面的部分不能去除的原因是因为在清空所有请求的时候需要用到cancel令牌
    // 所以必须在添加请求的时候就创建一个CancelToken取消令牌用于之后clearPending函数清空请求
    const originalAxios = this.originalAxios
    config.cancelToken = new originalAxios.CancelToken((cancel) => {
      // 创建当前请求放到map中
      pendingRequest.set(requestKey, cancel)
    })
  }

  // 去除所有列表里的请求(用于跳转路由等需要清空请求的情况)
  clearPending() {
    // 遍历map对象,用每个取消令牌逐一取消请求,起到清空所有请求的作用
    for (const [requestKey, cancelToken] of pendingRequest) {
      cancelToken(requestKey)
    }
    // 清空map对象
    pendingRequest.clear()
  }

  pendingReqHasKey(key) {
    return pendingRequest.has(key)
  }

  pendingReqdelKey(key) {
    pendingRequest.delete(key)
  }
}

export default throttleHttp

2. Reference throttleHttp.js in the encapsulated axios


import axios from 'axios'

/* eslint-disable */
const ThrottleHttp = new throttleHttp(axios)
axios.defaults.timeout = 86400000
axios.defaults.baseURL = basePublicUrl
axios.defaults.withCredentials = false
axios.defaults.headers.post['Content-Type'] = 'application/json'


// 如果走全局网关,看是否进行加密
// 请求拦截
axios.interceptors.request.use(function (config) {
  // 生成请求key
  const requestKey = ThrottleHttp.generateReqKey(config)
  if (ThrottleHttp.pendingReqHasKey(requestKey)) {
    return httpMark
  }
  // 把当前请求信息添加到pendingRequest对象中
  ThrottleHttp.addPendingRequest(config)
  return config
}, function (error) {
  // 这里出现错误可能是网络波动造成的,清空 pendingRequests 对象
  ThrottleHttp.clearPending()
  return Promise.reject(error.response)
})
axios.interceptors.response.use(function (response) {
  // 删除收集的请求key
  const requestKey = ThrottleHttp.generateReqKey(response.config)
  // 根据key删除当前请求
  ThrottleHttp.pendingReqdelKey(requestKey)
  // 收集报错信息
  return response
}, function (error) {
  // 删除收集的请求key
  const requestKey = ThrottleHttp.generateReqKey(error.config)
  //根据key删除当前请求
  ThrottleHttp.pendingReqdelKey(requestKey)
  return error
})

Guess you like

Origin blog.csdn.net/weixin_46996561/article/details/129917730