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