From 22af68428f77f0b09706849449f9f4ca5d795d1e Mon Sep 17 00:00:00 2001 From: mrkbear Date: Sun, 2 Jan 2022 18:29:21 +0800 Subject: [PATCH] Storage multi instance processing logic --- miniprogram/app.ts | 5 +- miniprogram/core/Storage.ts | 72 +++++++++++++++++++++++-- miniprogram/pages/Timetable/TestCore.ts | 13 +++-- 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/miniprogram/app.ts b/miniprogram/app.ts index f2661d8..c05849f 100644 --- a/miniprogram/app.ts +++ b/miniprogram/app.ts @@ -1,8 +1,9 @@ import { IAppAPIParam } from "./core/Api"; +import { IAppStorageParam, Storage, IStorageData } from "./core/Storage"; import { Logger, LevelLogLabel, LifeCycleLogLabel } from "./core/Logger"; -App({ +App({ /** * API 模块需要的全局数据 @@ -16,7 +17,7 @@ App({ /** * 存储缓存键值 */ - // storageCache: new Set(), + storage: new Map>(), /** * 小程序加载时 diff --git a/miniprogram/core/Storage.ts b/miniprogram/core/Storage.ts index 1d36a19..13d7eae 100644 --- a/miniprogram/core/Storage.ts +++ b/miniprogram/core/Storage.ts @@ -1,5 +1,13 @@ import { Logger, LogLabel, LevelLogLabel, colorRadio } from "./Logger"; +interface IAppStorageParam { + + /** + * storage 缓存 + */ + storage: Map> +} + /** * 状态 */ @@ -81,7 +89,8 @@ type IStorageData = { * 1. 该类封装了 wxStorage 操作 * 2. 全异步获取无阻塞 * 3. 使用数据缓缓冲区,优化高频存取 - * 4. + * 4. 如果全局范围内已存在莫键值 storage 的实例 + * 则此实例将链接到已存在实例 */ class Storage { @@ -103,18 +112,41 @@ class Storage { /** * 缓存数据 */ - private cache:T; + private _cache: T = {} as T; + private set cache(data: T) { + if (this.cacheStorage) { + for (const key in data) { + this.cacheStorage.cache[key] = data[key]; + } + } else { + for (const key in data) { + this._cache[key] = data[key]; + } + } + } + private get cache():T { + if (this.cacheStorage) return this.cacheStorage.cache; + else return this._cache; + } /** * cache 到 storage 等待列表 */ private saveWaiter:Waiter = new Waiter(); + /** + * 缓存对象 + */ + private cacheStorage:Storage | undefined; + /** * 将数据从 cache 同步到 storage */ public async save():Promise { + // 如果存在链接的实例 + if (this.cacheStorage) return this.cacheStorage.save(); + // 如果没有开始存储 // 发起一次异步读取 if(this.saveWaiter.state === StorageState.DONE) @@ -150,6 +182,24 @@ class Storage { }); } + /** + * 在缓存中搜索此键值的实例 + */ + private findStorageCache(): boolean { + let { storage: storageMap } = getApp(); + + // 查找缓存 + let storage = storageMap.get(this.key); + if (storage) { + this.cacheStorage = storage as Storage; + return true; + }; + + // 缓存此实例 + storageMap.set(this.key, this); + return false; + } + /** * 重置全部数据 */ @@ -164,13 +214,25 @@ class Storage { /** * @param defaultData 键值默认数据 */ - public constructor(key:string, defaultData:T) { + public constructor(key:string, defaultData?:T) { this.key = key; - this.defaultData = defaultData; + this.defaultData = defaultData ?? {} as T; this.StorageLogLabel = new LogLabel( `Storage:${ this.key }`, colorRadio(34, 230, 258) ); + // 如果已找到其他实力,将此实例链接到目标实例 + if (this.findStorageCache()) { + + // 设置默认值 + for (const key in this.defaultData) { + if (this.cache[key] === void 0) { + this.set(key, this.defaultData[key]); + } + } + return; + }; + // 读取数据到缓存 this.cache = wx.getStorageSync(this.key); @@ -205,4 +267,4 @@ class Storage { } export default Storage; -export { Storage, StorageState, Waiter }; \ No newline at end of file +export { Storage, StorageState, Waiter, IAppStorageParam, IStorageData }; \ No newline at end of file diff --git a/miniprogram/pages/Timetable/TestCore.ts b/miniprogram/pages/Timetable/TestCore.ts index f405248..2fc8e6c 100644 --- a/miniprogram/pages/Timetable/TestCore.ts +++ b/miniprogram/pages/Timetable/TestCore.ts @@ -15,6 +15,15 @@ implements Partial { be: 2 }); + let s2 = new Storage("test", { + be: 1, + aa: "abc" + }); + + s2.set("be", 4); + + console.log(s, s2); + setTimeout(() => { s.set("be", 12); }, 1000) @@ -55,9 +64,7 @@ implements Partial { } }).request().wait({ success: (d) => console.log(d) - }).wait({ - success: (d) => console.log(d) - }); + }) } }