|
|
- // 这里书写防抖,节流
- import request from "@/api/request";
-
- // 全局管理的存储状态
- const requestControlMap = new Map()
- const MAX_MAP_SIZE = 1000 // 防止内存轻易泄露
-
- // 请求标识生成器(更稳健的版本)
- const generateApiKey = (config) => {
- const { method, url, header, debounce, throttle } = config
- return `DEBOUNCE_AND_THROTTLE:${method}:${url}:${JSON.stringify(header)}:${debounce}:${throttle}`;
- }
-
- export default function http (config) {
- const apiKey = generateApiKey(config)
-
- // 空间保护
- if (requestControlMap.size > MAX_MAP_SIZE) {
- requestControlMap.clear() // 清空缓存
- // 类型保护
- }else if (config.debounce > 0 && config.throttle > 0) {
- throw new Error('请勿同时使用防抖和节流!')
- }
-
- // 如果有防抖的需求
- if (config.debounce > 0 ){
- clearTimeout(requestControlMap.get(apiKey)?.timer)
-
- return new Promise((resolve, reject) => {
- requestControlMap.set(apiKey, {
- timer: setTimeout(() => {
- // 防抖时间到了,清除缓存并发起请求
- requestControlMap.delete(apiKey)
- request(config).then(resolve).catch(reject)
- }, config.debounce),
- timeStamp: Date.now()
- })
- })
- }
-
- // 如果需要节流
- if (config.throttle > 0){
- const record = requestControlMap.get(apiKey)
- if (record && Date.now() - record.lastTime < config.throttle) {
- // 节流时间未到,不发起请求
- return Promise.reject(new Error('请求过于频繁'))
- }
- requestControlMap.set(apiKey, {
- lastTime: Date.now(),
- timeStamp: Date.now()
- })
- }
-
- // 正常发起请求
- return request(config)
- }
|