axios重复请求添加取消机制

397 阅读1分钟

一、背景

某个接口响应时间超过防抖的时间,此时重复点击,此时存在两次相同的请求,将第一次请求进行取消,保留最新请求。Github地址axios-abort

二、方案实现

axios版本大于v0.22.0 ,旧版CancelToken已经废弃,本次使用 AbortController 取消请求。

测试npm包 @sunrisecn/axios-abort

思路:根据url+method进行判断,使用map进行存储,key为url+method,value为signal数组,每次请求时判断是否是重复请求,如果是取消上次请求。

具体实现:

type TKey = {
  url: string
  method: string
}
class PendingStack {
  private pendingMap: Map<string, AbortController[]>
  constructor() {
    this.pendingMap = new Map()
  }
  // 添加接口的 使用map存储key为url+method value:使用数组存储
  public add({ url, method }: TKey): AbortSignal {
    const key = `${url}-${method}`
    const controller = new AbortController()
    const controllerList: AbortController[] = []
    if (this.pendingMap.has(key)) {
      this.pendingMap.get(key)?.push(controller)
    } else {
      controllerList.push(controller)
      this.pendingMap.set(key, controllerList)
    }
    return controller.signal
  }
   // 判断接口是否需要取消,每次有重复接口将前一条退出取消
  public judge({ url, method }: TKey) {
    const key = `${url}-${method}`
    const controllerList = this.pendingMap.get(key)
    if (Array.isArray(controllerList) && controllerList.length > 1) {
      controllerList?.shift()?.abort()
    }
  }
  // 移除接口
  public remove({ url, method }: TKey) {
    this.pendingMap.delete(`${url}-${method}`)
  }
  // 取消所有接口
  public removeAll() {
    this.pendingMap.forEach((controllerList) => {
      controllerList.shift()?.abort()
    })
    this.pendingMap.clear()
  }
}

export default new PendingStack()

三、项目使用

在request.js中使用

import axios from 'axios'
import abort from 'axios-abort'

const axios = axios.create(config)

axios.interceptors.request.use(
	config => {
		config.signal = abort.add({ url: config.url, method: config.method })
		abort.judge({ url: config.url, method: config.method })
		return config
	},
	error => Promise.reject(error)
)

axios.interceptors.response.use(
	response => {
		abort.remove({ url: response.config.url, method: response.config.method })
		return response
	},
	error => Promise.reject(error)
)

API

  • add
    • 添加接口取消
  • judge
    • 判断是否满足取消条件
  • remove
    • 取消单个接口
  • removeAll
    • 取消所有接口