展品维保小程序前端代码接口
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.

55 lines
1.6 KiB

2 weeks ago
  1. // 这里书写防抖,节流
  2. import request from "@/api/request";
  3. // 全局管理的存储状态
  4. const requestControlMap = new Map()
  5. const MAX_MAP_SIZE = 1000 // 防止内存轻易泄露
  6. // 请求标识生成器(更稳健的版本)
  7. const generateApiKey = (config) => {
  8. const { method, url, header, debounce, throttle } = config
  9. return `DEBOUNCE_AND_THROTTLE:${method}:${url}:${JSON.stringify(header)}:${debounce}:${throttle}`;
  10. }
  11. export default function http (config) {
  12. const apiKey = generateApiKey(config)
  13. // 空间保护
  14. if (requestControlMap.size > MAX_MAP_SIZE) {
  15. requestControlMap.clear() // 清空缓存
  16. // 类型保护
  17. }else if (config.debounce > 0 && config.throttle > 0) {
  18. throw new Error('请勿同时使用防抖和节流!')
  19. }
  20. // 如果有防抖的需求
  21. if (config.debounce > 0 ){
  22. clearTimeout(requestControlMap.get(apiKey)?.timer)
  23. return new Promise((resolve, reject) => {
  24. requestControlMap.set(apiKey, {
  25. timer: setTimeout(() => {
  26. // 防抖时间到了,清除缓存并发起请求
  27. requestControlMap.delete(apiKey)
  28. request(config).then(resolve).catch(reject)
  29. }, config.debounce),
  30. timeStamp: Date.now()
  31. })
  32. })
  33. }
  34. // 如果需要节流
  35. if (config.throttle > 0){
  36. const record = requestControlMap.get(apiKey)
  37. if (record && Date.now() - record.lastTime < config.throttle) {
  38. // 节流时间未到,不发起请求
  39. return Promise.reject(new Error('请求过于频繁'))
  40. }
  41. requestControlMap.set(apiKey, {
  42. lastTime: Date.now(),
  43. timeStamp: Date.now()
  44. })
  45. }
  46. // 正常发起请求
  47. return request(config)
  48. }