| // 这里书写防抖,节流 | |
| 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) | |
| }
 |