axios中防止相同接口并发请求

27 阅读1分钟

request.js

import axios from 'axios'
const service = axios.create({
  baseURL: 'baseURL'
})
const pendingRequests = new Map()
service.interceptors.request.use(
  config => {
    const requestKey = `${config.url}/${JSON.stringify(config.params)}/${JSON.stringify(config.data)}&request_type=${
      config.method
    }`
    // 防止相同接口并发请求
    if (pendingRequests.has(requestKey)) {
      config.cancelToken = new axios.CancelToken(cancel => {
        // cancel 函数的参数会作为 promise 的 error 被捕获
        cancel(`重复的请求被主动拦截: ${config.url}`)
      })
    } else {
      pendingRequests.set(requestKey, config)
      config.requestKey = requestKey
    }
    return config
  },
  error => {
    // do something with request error
    // 这里出现错误可能是网络波动造成的,清空 pendingRequests 对象
    pendingRequests.clear()
    console.log(error) // for debug
    return Promise.reject(error)
  }
)
service.interceptors.response.use(
  response => {
    const { config } = response
    const requestKey = config.requestKey
    pendingRequests.delete(requestKey)
  },
  error => {
    pendingRequests.clear()
    return Promise.reject(error)
  }
)
service.clearRequestList = () => {
  pendingRequests.clear()
}

export default service

路由切换时清除当前页面缓存的接口

router.beforeEach(async(to, from, next) => {
  request.clearRequestList()
})