Skip to content

Commit b62781e

Browse files
cyfung1031CodFrm
andauthored
♻️ 优化ReduxStore与广播机制 (#729)
* 优化ReduxStore与广播机制 * 其他代码优化 * lint * 不忽略排序出錯 * 根據指示修改 * 根據指示修改 * updateScriptListMultiple -> updateEntry * 刪去未使用代碼 --------- Co-authored-by: 王一之 <yz@ggnb.top>
1 parent 4e55c06 commit b62781e

23 files changed

Lines changed: 975 additions & 561 deletions

File tree

src/app/repo/repo.ts

Lines changed: 215 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,149 @@
11
// 加载全局缓存
22

3-
let loadCachePromise: Promise<any> | undefined = undefined;
4-
let cache: { [key: string]: any } | undefined = undefined;
3+
let loadCachePromise: Promise<Partial<Record<string, any>>> | undefined = undefined;
4+
let cache: Partial<Record<string, any>> | undefined = undefined;
55

66
// 加载数据到缓存
7-
function loadCache(): Promise<any> {
7+
function loadCache(): Promise<Partial<Record<string, any>>> {
88
if (cache) {
99
return Promise.resolve(cache);
1010
}
11-
if (loadCachePromise) {
12-
return loadCachePromise;
11+
if (!loadCachePromise) {
12+
loadCachePromise = new Promise<Partial<Record<string, any>>>((resolve) => {
13+
chrome.storage.local.get((result: Partial<Record<string, any>> | undefined) => {
14+
const lastError = chrome.runtime.lastError;
15+
if (lastError) {
16+
console.error("chrome.runtime.lastError in chrome.storage.local.get:", lastError);
17+
// 无视storage API错误,继续执行
18+
}
19+
cache = result || {};
20+
loadCachePromise = undefined;
21+
resolve(cache);
22+
});
23+
});
1324
}
14-
loadCachePromise = new Promise((resolve) => {
15-
chrome.storage.local.get((result: { [key: string]: any } | undefined) => {
25+
return loadCachePromise;
26+
}
27+
28+
function saveCacheAndStorage<T>(key: string, value: T): Promise<T> {
29+
return Promise.all([
30+
loadCache().then((cache) => {
31+
cache[key] = value;
32+
}),
33+
new Promise<void>((resolve) => {
34+
chrome.storage.local.set({ [key]: value }, () => {
35+
const lastError = chrome.runtime.lastError;
36+
if (lastError) {
37+
console.error("chrome.runtime.lastError in chrome.storage.local.set:", lastError);
38+
// 无视storage API错误,继续执行
39+
}
40+
resolve();
41+
});
42+
}),
43+
]).then(() => value);
44+
}
45+
46+
function saveStorage<T>(key: string, value: T): Promise<T> {
47+
return new Promise((resolve) => {
48+
chrome.storage.local.set(
49+
{
50+
[key]: value,
51+
},
52+
() => {
53+
const lastError = chrome.runtime.lastError;
54+
if (lastError) {
55+
console.error("chrome.runtime.lastError in chrome.storage.local.set:", lastError);
56+
// 无视storage API错误,继续执行
57+
}
58+
resolve(value);
59+
}
60+
);
61+
});
62+
}
63+
64+
function saveStorageRecord(record: Partial<Record<string, any>>): Promise<void> {
65+
return new Promise((resolve) => {
66+
chrome.storage.local.set(record, () => {
67+
const lastError = chrome.runtime.lastError;
68+
if (lastError) {
69+
console.error("chrome.runtime.lastError in chrome.storage.local.set:", lastError);
70+
// 无视storage API错误,继续执行
71+
}
72+
resolve();
73+
});
74+
});
75+
}
76+
77+
function getCache(key: string): Promise<any> {
78+
return loadCache().then((cache) => {
79+
if (cache[key]) {
80+
return Object.assign({}, cache[key]);
81+
}
82+
return cache[key];
83+
});
84+
}
85+
86+
function getStorage(key: string): Promise<any> {
87+
return new Promise((resolve) => {
88+
chrome.storage.local.get(key, (result) => {
1689
const lastError = chrome.runtime.lastError;
1790
if (lastError) {
1891
console.error("chrome.runtime.lastError in chrome.storage.local.get:", lastError);
1992
// 无视storage API错误,继续执行
2093
}
21-
cache = result;
22-
resolve(cache);
94+
resolve(result[key]);
2395
});
2496
});
25-
return loadCachePromise;
2697
}
2798

28-
function saveCache(key: string, value: any) {
29-
loadCache().then(() => {
30-
cache![key] = value;
99+
function getStorageRecord(keys: string[]): Promise<Partial<Record<string, any>>> {
100+
return new Promise((resolve) => {
101+
chrome.storage.local.get(keys, (result) => {
102+
const lastError = chrome.runtime.lastError;
103+
if (lastError) {
104+
console.error("chrome.runtime.lastError in chrome.storage.local.get:", lastError);
105+
// 无视storage API错误,继续执行
106+
}
107+
resolve(result);
108+
});
31109
});
32-
return chrome.storage.local.set({ [key]: value });
33110
}
34111

35112
function deleteCache(key: string) {
36-
loadCache().then(() => {
37-
delete cache![key];
113+
return loadCache().then((cache) => {
114+
delete cache[key];
115+
});
116+
}
117+
118+
function deleteStorage(key: string) {
119+
return new Promise<void>((resolve) => {
120+
chrome.storage.local.remove(key, () => {
121+
const lastError = chrome.runtime.lastError;
122+
if (lastError) {
123+
console.error("chrome.runtime.lastError in chrome.storage.local.remove:", lastError);
124+
// 无视storage API错误,继续执行
125+
}
126+
resolve();
127+
});
128+
});
129+
}
130+
function deletesStorage(keys: string[]) {
131+
return new Promise<void>((resolve, reject) => {
132+
chrome.storage.local.remove(keys, () => {
133+
const lastError = chrome.runtime.lastError;
134+
if (lastError) {
135+
console.error("chrome.runtime.lastError in chrome.storage.local.remove:", lastError);
136+
// 无视storage API错误,继续执行
137+
reject();
138+
}
139+
resolve();
140+
});
141+
}).catch(async () => {
142+
// fallback
143+
for (const key of keys) {
144+
await deleteStorage(key);
145+
}
38146
});
39-
return chrome.storage.local.remove(key);
40147
}
41148

42149
export abstract class Repo<T> {
@@ -58,44 +165,41 @@ export abstract class Repo<T> {
58165
}
59166

60167
protected async _save(key: string, val: T): Promise<T> {
61-
return new Promise((resolve) => {
62-
const data = {
63-
[this.joinKey(key)]: val,
64-
};
65-
if (this.useCache) {
66-
return saveCache(this.joinKey(key), val).then(() => {
67-
return resolve(val);
68-
});
69-
}
70-
chrome.storage.local.set(data, () => {
71-
const lastError = chrome.runtime.lastError;
72-
if (lastError) {
73-
console.error("chrome.runtime.lastError in chrome.storage.local.set:", lastError);
74-
// 无视storage API错误,继续执行
75-
}
76-
resolve(val);
77-
});
78-
});
168+
key = this.joinKey(key);
169+
if (this.useCache) {
170+
return saveCacheAndStorage(key, val);
171+
}
172+
return saveStorage(key, val);
79173
}
80174

81175
public get(key: string): Promise<T | undefined> {
176+
key = this.joinKey(key);
177+
if (this.useCache) {
178+
return getCache(key);
179+
}
180+
return getStorage(key);
181+
}
182+
183+
public gets(keys: string[]): Promise<(T | undefined)[]> {
184+
keys = keys.map((key) => this.joinKey(key));
82185
if (this.useCache) {
83186
return loadCache().then((cache) => {
84-
if (cache[this.joinKey(key)]) {
85-
return Object.assign({}, cache[this.joinKey(key)]);
86-
}
87-
return cache[this.joinKey(key)];
187+
return keys.map((key) => {
188+
if (cache[key]) {
189+
return Object.assign({}, cache[key]);
190+
}
191+
return cache[key];
192+
});
88193
});
89194
}
90195
return new Promise((resolve) => {
91-
key = this.joinKey(key);
92-
chrome.storage.local.get(key, (result) => {
196+
chrome.storage.local.get(keys, (result) => {
93197
const lastError = chrome.runtime.lastError;
94198
if (lastError) {
95199
console.error("chrome.runtime.lastError in chrome.storage.local.get:", lastError);
96200
// 无视storage API错误,继续执行
97201
}
98-
resolve(result[key]);
202+
resolve(keys.map((key) => result[key]));
99203
});
100204
});
101205
}
@@ -123,69 +227,98 @@ export abstract class Repo<T> {
123227
});
124228
});
125229
}
126-
const loadData = () => {
127-
return new Promise<T[]>((resolve) => {
128-
chrome.storage.local.get((result: { [key: string]: T }) => {
129-
const lastError = chrome.runtime.lastError;
130-
if (lastError) {
131-
console.error("chrome.runtime.lastError in chrome.storage.local.get:", lastError);
132-
// 无视storage API错误,继续执行
133-
}
134-
resolve(this.filter(result, filters));
135-
});
230+
return new Promise<T[]>((resolve) => {
231+
chrome.storage.local.get((result: { [key: string]: T }) => {
232+
const lastError = chrome.runtime.lastError;
233+
if (lastError) {
234+
console.error("chrome.runtime.lastError in chrome.storage.local.get:", lastError);
235+
// 无视storage API错误,继续执行
236+
}
237+
resolve(this.filter(result, filters));
136238
});
137-
};
138-
return loadData();
239+
});
139240
}
140241

141242
async findOne(filters?: (key: string, value: T) => boolean): Promise<T | undefined> {
142-
const list = await this.find(filters);
143-
if (list.length > 0) {
144-
return list[0];
145-
}
146-
return undefined;
243+
return this.find(filters).then((list) => {
244+
if (list.length > 0) {
245+
return list[0];
246+
}
247+
return undefined;
248+
});
147249
}
148250

149-
public delete(key: string) {
251+
public delete(key: string): Promise<void> {
252+
key = this.joinKey(key);
150253
if (this.useCache) {
151-
return deleteCache(this.joinKey(key));
254+
return Promise.all([deleteCache(key), deleteStorage(key)]).then(() => undefined);
152255
}
153-
return new Promise<void>((resolve) => {
154-
chrome.storage.local.remove(this.joinKey(key), () => {
155-
const lastError = chrome.runtime.lastError;
156-
if (lastError) {
157-
console.error("chrome.runtime.lastError in chrome.storage.local.remove:", lastError);
158-
// 无视storage API错误,继续执行
256+
return deleteStorage(key);
257+
}
258+
259+
public deletes(keys: string[]): Promise<void> {
260+
keys = keys.map((key) => this.joinKey(key));
261+
if (this.useCache) {
262+
return loadCache().then((cache) => {
263+
for (const key of keys) {
264+
delete cache[key];
159265
}
160-
resolve();
266+
return deletesStorage(keys);
161267
});
162-
});
268+
}
269+
return deletesStorage(keys);
163270
}
164271

272+
// 資料不存在時無法更新, 回傳 false
273+
// 資料存在時進行Object.assign更新,回傳更新後的資料項目
165274
update(key: string, val: Partial<T>): Promise<T | false> {
275+
key = this.joinKey(key);
166276
if (this.useCache) {
167277
return loadCache().then((cache) => {
168-
const data = cache[this.joinKey(key)];
278+
const data = cache[key] as T;
169279
if (data) {
170280
Object.assign(data, val);
171-
return saveCache(this.joinKey(key), data).then(() => {
172-
return data;
173-
});
281+
return saveCacheAndStorage(key, data) as Promise<T | false>;
174282
}
175283
return false;
176284
});
177285
}
178-
return new Promise((resolve) => {
179-
this.get(key).then((result) => {
180-
if (result) {
181-
Object.assign(result, val);
182-
this._save(key, result).then(() => {
183-
resolve(result);
184-
});
185-
} else {
186-
resolve(false);
286+
return getStorage(key).then((result) => {
287+
if (result) {
288+
Object.assign(result, val);
289+
return saveStorage(key, result) as T;
290+
} else {
291+
return false;
292+
}
293+
});
294+
}
295+
296+
updates(keys: string[], val: Partial<T>): Promise<(T | false)[]> {
297+
keys = keys.map((key) => this.joinKey(key));
298+
if (this.useCache) {
299+
return loadCache().then((cache) =>
300+
Promise.all(
301+
keys.map((key) => {
302+
const data = cache[key] as T;
303+
if (data) {
304+
Object.assign(data, val);
305+
return saveCacheAndStorage(key, data) as Promise<T>;
306+
}
307+
return false;
308+
})
309+
)
310+
);
311+
}
312+
return getStorageRecord(keys).then((record) => {
313+
const result = keys.map((key) => {
314+
const o = record[key];
315+
if (o) {
316+
Object.assign(o, val);
317+
return o as T;
187318
}
319+
return false;
188320
});
321+
return saveStorageRecord(record).then(() => result);
189322
});
190323
}
191324

0 commit comments

Comments
 (0)