展品维保小程序前端代码接口
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

56 lines
1.6 KiB

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