1
+ // 加载全局缓存
2
+
3
+ let loadCachePromise : Promise < any > | undefined = undefined ;
4
+ let cache : { [ key : string ] : any } | undefined = undefined ;
5
+
6
+ // 加载数据到缓存
7
+ function loadCache ( ) : Promise < any > {
8
+ if ( cache ) {
9
+ return Promise . resolve ( cache ) ;
10
+ }
11
+ if ( loadCachePromise ) {
12
+ return loadCachePromise ;
13
+ }
14
+ loadCachePromise = new Promise ( ( resolve ) => {
15
+ chrome . storage . local . get ( ( result ) => {
16
+ cache = result ;
17
+ resolve ( cache ) ;
18
+ } ) ;
19
+ } ) ;
20
+ return loadCachePromise ;
21
+ }
22
+
23
+ function saveCache ( key : string , value : any ) {
24
+ loadCache ( ) . then ( ( ) => {
25
+ cache ! [ key ] = value ;
26
+ } ) ;
27
+ return chrome . storage . local . set ( { [ key ] : value } ) ;
28
+ }
29
+
30
+ function deleteCache ( key : string ) {
31
+ loadCache ( ) . then ( ( ) => {
32
+ delete cache ! [ key ] ;
33
+ } ) ;
34
+ return chrome . storage . local . remove ( key ) ;
35
+ }
36
+
1
37
export abstract class Repo < T > {
38
+ // 开启缓存,不重复加载数据
39
+ useCache : boolean = false ;
40
+
2
41
constructor ( protected prefix : string ) {
3
42
if ( ! prefix . endsWith ( ":" ) ) {
4
43
this . prefix += ":" ;
5
44
}
6
45
}
7
46
47
+ enableCache ( ) {
48
+ this . useCache = true ;
49
+ }
50
+
8
51
protected joinKey ( key : string ) {
9
52
return this . prefix + key ;
10
53
}
@@ -14,13 +57,26 @@ export abstract class Repo<T> {
14
57
const data = {
15
58
[ this . joinKey ( key ) ] : val ,
16
59
} ;
60
+ if ( this . useCache ) {
61
+ return saveCache ( this . joinKey ( key ) , val ) . then ( ( ) => {
62
+ return resolve ( val ) ;
63
+ } ) ;
64
+ }
17
65
chrome . storage . local . set ( data , ( ) => {
18
66
resolve ( val ) ;
19
67
} ) ;
20
68
} ) ;
21
69
}
22
70
23
71
public get ( key : string ) : Promise < T | undefined > {
72
+ if ( this . useCache ) {
73
+ return loadCache ( ) . then ( ( cache ) => {
74
+ if ( cache [ this . joinKey ( key ) ] ) {
75
+ return Object . assign ( { } , cache [ this . joinKey ( key ) ] ) ;
76
+ }
77
+ return cache [ this . joinKey ( key ) ] ;
78
+ } ) ;
79
+ }
24
80
return new Promise ( ( resolve ) => {
25
81
key = this . joinKey ( key ) ;
26
82
chrome . storage . local . get ( key , ( result ) => {
@@ -29,34 +85,51 @@ export abstract class Repo<T> {
29
85
} ) ;
30
86
}
31
87
32
- public find ( filters ?: ( key : string , value : T ) => boolean ) : Promise < T [ ] > {
33
- return new Promise ( ( resolve ) => {
34
- chrome . storage . local . get ( ( result ) => {
35
- const ret = [ ] ;
36
- for ( const key in result ) {
37
- if ( key . startsWith ( this . prefix ) && ( ! filters || filters ( key , result [ key ] ) ) ) {
38
- ret . push ( result [ key ] ) ;
39
- }
88
+ private filter ( data : { [ key : string ] : T } , filters ?: ( key : string , value : T ) => boolean ) : T [ ] {
89
+ const ret : T [ ] = [ ] ;
90
+ for ( const key in data ) {
91
+ if ( key . startsWith ( this . prefix ) ) {
92
+ if ( ! filters || filters ( key , data [ key ] ) ) {
93
+ ret . push ( data [ key ] ) ;
40
94
}
41
- resolve ( ret ) ;
42
- } ) ;
43
- } ) ;
95
+ }
96
+ }
97
+ return ret ;
44
98
}
45
99
46
- findOne ( filters ?: ( key : string , value : T ) => boolean ) : Promise < T | undefined > {
47
- return new Promise ( ( resolve ) => {
48
- chrome . storage . local . get ( ( result ) => {
49
- for ( const key in result ) {
50
- if ( key . startsWith ( this . prefix ) && ( ! filters || filters ( key , result [ key ] ) ) ) {
51
- return resolve ( result [ key ] ) ;
100
+ public async find ( filters ?: ( key : string , value : T ) => boolean ) : Promise < T [ ] > {
101
+ if ( this . useCache ) {
102
+ return loadCache ( ) . then ( ( cache ) => {
103
+ return this . filter ( cache , filters ) . map ( ( item ) => {
104
+ if ( item ) {
105
+ return Object . assign ( { } , item ) ;
52
106
}
53
- }
54
- resolve ( undefined ) ;
107
+ return item ;
108
+ } ) ;
55
109
} ) ;
56
- } ) ;
110
+ }
111
+ const loadData = ( ) => {
112
+ return new Promise < T [ ] > ( ( resolve ) => {
113
+ chrome . storage . local . get ( ( result ) => {
114
+ resolve ( this . filter ( result , filters ) ) ;
115
+ } ) ;
116
+ } ) ;
117
+ } ;
118
+ return loadData ( ) ;
119
+ }
120
+
121
+ async findOne ( filters ?: ( key : string , value : T ) => boolean ) : Promise < T | undefined > {
122
+ const list = await this . find ( filters ) ;
123
+ if ( list . length > 0 ) {
124
+ return list [ 0 ] ;
125
+ }
126
+ return undefined ;
57
127
}
58
128
59
129
public delete ( key : string ) {
130
+ if ( this . useCache ) {
131
+ return deleteCache ( this . joinKey ( key ) ) ;
132
+ }
60
133
return new Promise < void > ( ( resolve ) => {
61
134
chrome . storage . local . remove ( this . joinKey ( key ) , ( ) => {
62
135
resolve ( ) ;
@@ -65,6 +138,18 @@ export abstract class Repo<T> {
65
138
}
66
139
67
140
update ( key : string , val : Partial < T > ) : Promise < T | false > {
141
+ if ( this . useCache ) {
142
+ return loadCache ( ) . then ( ( cache ) => {
143
+ const data = cache [ this . joinKey ( key ) ] ;
144
+ if ( data ) {
145
+ Object . assign ( data , val ) ;
146
+ return saveCache ( this . joinKey ( key ) , data ) . then ( ( ) => {
147
+ return data ;
148
+ } ) ;
149
+ }
150
+ return false ;
151
+ } ) ;
152
+ }
68
153
return new Promise ( ( resolve ) => {
69
154
this . get ( key ) . then ( ( result ) => {
70
155
if ( result ) {
@@ -80,16 +165,6 @@ export abstract class Repo<T> {
80
165
}
81
166
82
167
all ( ) : Promise < T [ ] > {
83
- return new Promise ( ( resolve ) => {
84
- chrome . storage . local . get ( ( result ) => {
85
- const ret = [ ] ;
86
- for ( const key in result ) {
87
- if ( key . startsWith ( this . prefix ) ) {
88
- ret . push ( result [ key ] ) ;
89
- }
90
- }
91
- resolve ( ret ) ;
92
- } ) ;
93
- } ) ;
168
+ return this . find ( ) ;
94
169
}
95
170
}
0 commit comments