cache.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import qs from 'qs'
  2. import get from 'lodash/get'
  3. import { Manager } from '@/utils/manager'
  4. import http from '@/utils/http'
  5. // 缓存
  6. let _cache = {}
  7. // 队列
  8. let _queue = {}
  9. export function load ({
  10. res,
  11. action,
  12. apiVersion = 'v2',
  13. resPath,
  14. actionArgs = {},
  15. useManager = true,
  16. }) {
  17. return new Promise((resolve, reject) => {
  18. // 根据params和res生成唯一key
  19. const _params = { ...actionArgs.params }
  20. const _data = { ...actionArgs.data }
  21. const requestMethod = actionArgs.method || 'GET'
  22. if (_params.$t) delete _params.$t
  23. const stringifyKey = qs.stringify(requestMethod === 'GET' ? _params : _data)
  24. let key = `${res}$$${stringifyKey}`
  25. if (!useManager && actionArgs.url) {
  26. key = `${res}$$${actionArgs.url}$$${stringifyKey}`
  27. }
  28. const value = _cache[key]
  29. // 有数据则直接返回
  30. if (value) {
  31. return resolve(value)
  32. }
  33. // 无数据加入请求队列并缓存
  34. if (_queue[key]) {
  35. _queue[key].add(resolve, reject)
  36. } else {
  37. // refresh 突破缓存限制
  38. if (res === 'usages') {
  39. if (actionArgs.params) actionArgs.params.refresh = true
  40. if (actionArgs.data) actionArgs.data.refresh = true
  41. }
  42. _queue[key] = new Loader({ key, res, action, apiVersion, resolve, reject, actionArgs, resPath, useManager })
  43. setTimeout(() => {
  44. _queue[key] && _queue[key].load()
  45. }, 100)
  46. }
  47. })
  48. }
  49. export function clear () {
  50. _cache = {}
  51. _queue = {}
  52. }
  53. class Loader {
  54. constructor ({ key, res, action, apiVersion, resolve, reject, actionArgs, resPath, useManager }) {
  55. this.key = key
  56. this.res = res
  57. this.action = action
  58. this.queue = [[resolve, reject]]
  59. this.apiVersion = apiVersion
  60. this.actionArgs = actionArgs
  61. this.resPath = resPath
  62. this.useManager = useManager
  63. }
  64. add (resolve, reject) {
  65. this.queue.push([resolve, reject])
  66. }
  67. async load () {
  68. let manager
  69. try {
  70. let response
  71. if (this.useManager) {
  72. manager = new Manager(this.res, this.apiVersion)
  73. response = await manager[this.action](this.actionArgs)
  74. } else {
  75. response = await http(this.actionArgs)
  76. }
  77. const data = get(response, this.resPath)
  78. _cache[this.key] = data
  79. for (let i = 0; i < this.queue.length; i++) {
  80. const cb = this.queue[i]
  81. cb[0](data)
  82. }
  83. delete _queue[this.key]
  84. return data
  85. } catch (error) {
  86. for (let i = 0; i < this.queue.length; i++) {
  87. const cb = this.queue[i]
  88. cb[1](error)
  89. }
  90. delete _queue[this.key]
  91. throw error
  92. } finally {
  93. manager = null
  94. }
  95. }
  96. }