提交 | 用户 | age
|
f57eb9
|
1 |
export interface Cache<V = any> { |
V |
2 |
value?: V; |
|
3 |
timeoutId?: ReturnType<typeof setTimeout>; |
|
4 |
time?: number; |
|
5 |
alive?: number; |
|
6 |
} |
|
7 |
|
|
8 |
const NOT_ALIVE = 0; |
|
9 |
|
|
10 |
export class Memory<T = any, V = any> { |
|
11 |
private cache: { [key in keyof T]?: Cache<V> } = {}; |
|
12 |
private alive: number; |
|
13 |
|
|
14 |
constructor(alive = NOT_ALIVE) { |
|
15 |
// Unit second |
|
16 |
this.alive = alive * 1000; |
|
17 |
} |
|
18 |
|
|
19 |
get getCache() { |
|
20 |
return this.cache; |
|
21 |
} |
|
22 |
|
|
23 |
setCache(cache) { |
|
24 |
this.cache = cache; |
|
25 |
} |
|
26 |
|
|
27 |
// get<K extends keyof T>(key: K) { |
|
28 |
// const item = this.getItem(key); |
|
29 |
// const time = item?.time; |
f91d77
|
30 |
// if (!isNil(time) && time < new Date().getTime()) { |
f57eb9
|
31 |
// this.remove(key); |
V |
32 |
// } |
|
33 |
// return item?.value ?? undefined; |
|
34 |
// } |
|
35 |
|
|
36 |
get<K extends keyof T>(key: K) { |
|
37 |
return this.cache[key]; |
|
38 |
} |
|
39 |
|
|
40 |
set<K extends keyof T>(key: K, value: V, expires?: number) { |
|
41 |
let item = this.get(key); |
|
42 |
|
|
43 |
if (!expires || (expires as number) <= 0) { |
|
44 |
expires = this.alive; |
|
45 |
} |
|
46 |
if (item) { |
|
47 |
if (item.timeoutId) { |
|
48 |
clearTimeout(item.timeoutId); |
|
49 |
item.timeoutId = undefined; |
|
50 |
} |
|
51 |
item.value = value; |
|
52 |
} else { |
|
53 |
item = { value, alive: expires }; |
|
54 |
this.cache[key] = item; |
|
55 |
} |
|
56 |
|
|
57 |
if (!expires) { |
|
58 |
return value; |
|
59 |
} |
159d90
|
60 |
const now = new Date().getTime(); |
0c633f
|
61 |
/** |
C |
62 |
* Prevent overflow of the setTimeout Maximum delay value |
|
63 |
* Maximum delay value 2,147,483,647 ms |
|
64 |
* https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value |
|
65 |
*/ |
|
66 |
item.time = expires > now ? expires : now + expires; |
159d90
|
67 |
item.timeoutId = setTimeout( |
V |
68 |
() => { |
|
69 |
this.remove(key); |
|
70 |
}, |
56a966
|
71 |
expires > now ? expires - now : expires, |
159d90
|
72 |
); |
f57eb9
|
73 |
|
V |
74 |
return value; |
|
75 |
} |
|
76 |
|
|
77 |
remove<K extends keyof T>(key: K) { |
|
78 |
const item = this.get(key); |
|
79 |
Reflect.deleteProperty(this.cache, key); |
|
80 |
if (item) { |
|
81 |
clearTimeout(item.timeoutId!); |
|
82 |
return item.value; |
|
83 |
} |
|
84 |
} |
|
85 |
|
|
86 |
resetCache(cache: { [K in keyof T]: Cache }) { |
|
87 |
Object.keys(cache).forEach((key) => { |
00fca0
|
88 |
const k = key as any as keyof T; |
f57eb9
|
89 |
const item = cache[k]; |
V |
90 |
if (item && item.time) { |
|
91 |
const now = new Date().getTime(); |
f6cef1
|
92 |
const expire = item.time; |
f57eb9
|
93 |
if (expire > now) { |
V |
94 |
this.set(k, item.value, expire); |
|
95 |
} |
|
96 |
} |
|
97 |
}); |
|
98 |
} |
|
99 |
|
|
100 |
clear() { |
|
101 |
Object.keys(this.cache).forEach((key) => { |
|
102 |
const item = this.cache[key]; |
|
103 |
item.timeoutId && clearTimeout(item.timeoutId); |
|
104 |
}); |
|
105 |
this.cache = {}; |
|
106 |
} |
|
107 |
} |