-
Notifications
You must be signed in to change notification settings - Fork 103
/
useCachePlugin.ts
134 lines (121 loc) · 3.65 KB
/
useCachePlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { ref, watchEffect, onScopeDispose } from 'vue'
import { UseRequestPlugin } from '../types'
import * as cache from '../utils/cache'
import { CachedData } from '../utils/cache'
import * as cachePromise from '../utils/cachePromise'
import * as cacheSubscribe from '../utils/cacheSubscribe'
const useCachePlugin: UseRequestPlugin<unknown, unknown[]> = (
fetchInstance,
{
cacheKey,
cacheTime = 5 * 60 * 1000,
staleTime = 0,
setCache: customSetCache,
getCache: customGetCache,
},
) => {
const unSubscribeRef = ref<() => void>()
const currentPromiseRef = ref<Promise<any>>()
const _setCache = (key: string, cachedData: CachedData) => {
if (customSetCache) {
customSetCache(cachedData)
} else {
cache.setCache(key, cacheTime, cachedData)
}
cacheSubscribe.trigger(key, cachedData.data)
}
const _getCache = (key: string, params: any[] = []) => {
if (customGetCache) {
return customGetCache(params)
}
return cache.getCache(key)
}
watchEffect(() => {
if (!cacheKey) {
return
}
// 获取初始化的data
const cacheData = _getCache(cacheKey)
if (cacheData && Object.hasOwnProperty.call(cacheData, 'data')) {
fetchInstance.state.data = cacheData.data
fetchInstance.state.params = cacheData.params
if (staleTime === -1 || new Date().getTime() - cacheData.time <= staleTime) {
fetchInstance.state.loading = false
}
}
// 如果存在相同的cacheKey,触发更新
unSubscribeRef.value = cacheSubscribe.subscribe(cacheKey, data => {
fetchInstance.setState({ data })
})
})
onScopeDispose(() => {
unSubscribeRef.value?.()
})
if (!cacheKey) {
return {}
}
return {
name: "cachePlugin",
onBefore: params => {
const cacheData = _getCache(cacheKey, params)
if (!cacheData || !Object.hasOwnProperty.call(cacheData, 'data')) {
return {}
}
// 数据是新鲜就停止请求
if (staleTime === -1 || new Date().getTime() - cacheData.time <= staleTime) {
return {
loading: false,
data: cacheData?.data,
returnNow: true,
}
} else {
// 数据不新鲜,则返回data,并且继续发送请求
return {
data: cacheData?.data,
}
}
},
onRequest: (service, args) => {
let servicePromise = cachePromise.getCachePromise(cacheKey)
// 如果存在servicePromise,并且它没有被触发,则使用它
if (servicePromise && servicePromise !== currentPromiseRef.value) {
return { servicePromise }
}
servicePromise = service(...args)
currentPromiseRef.value = servicePromise
cachePromise.setCachePromise(cacheKey, servicePromise)
return { servicePromise }
},
onSuccess: (data, params) => {
if (cacheKey) {
// 取消更新,避免反复触发自己
unSubscribeRef.value?.()
_setCache(cacheKey, {
data,
params,
time: new Date().getTime(),
})
// 触发器更新
unSubscribeRef.value = cacheSubscribe.subscribe(cacheKey, d => {
fetchInstance.setState({ data: d })
})
}
},
onMutate: data => {
if (cacheKey) {
// 取消更新,避免反复触发自己
unSubscribeRef.value?.()
_setCache(cacheKey, {
data,
params: fetchInstance.state.params,
time: new Date().getTime(),
})
// 触发器更新
unSubscribeRef.value = cacheSubscribe.subscribe(cacheKey, d => {
fetchInstance.setState({ data: d })
})
}
},
}
}
export default useCachePlugin