Storage multi instance processing logic
This commit is contained in:
parent
4f49012bb6
commit
22af68428f
@ -1,8 +1,9 @@
|
|||||||
import { IAppAPIParam } from "./core/Api";
|
import { IAppAPIParam } from "./core/Api";
|
||||||
|
import { IAppStorageParam, Storage, IStorageData } from "./core/Storage";
|
||||||
import { Logger, LevelLogLabel, LifeCycleLogLabel } from "./core/Logger";
|
import { Logger, LevelLogLabel, LifeCycleLogLabel } from "./core/Logger";
|
||||||
|
|
||||||
|
|
||||||
App<IAppAPIParam>({
|
App<IAppAPIParam & IAppStorageParam>({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API 模块需要的全局数据
|
* API 模块需要的全局数据
|
||||||
@ -16,7 +17,7 @@ App<IAppAPIParam>({
|
|||||||
/**
|
/**
|
||||||
* 存储缓存键值
|
* 存储缓存键值
|
||||||
*/
|
*/
|
||||||
// storageCache: new Set<string>(),
|
storage: new Map<string, Storage<IStorageData>>(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序加载时
|
* 小程序加载时
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
import { Logger, LogLabel, LevelLogLabel, colorRadio } from "./Logger";
|
import { Logger, LogLabel, LevelLogLabel, colorRadio } from "./Logger";
|
||||||
|
|
||||||
|
interface IAppStorageParam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* storage 缓存
|
||||||
|
*/
|
||||||
|
storage: Map<string, Storage<IStorageData>>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*/
|
*/
|
||||||
@ -81,7 +89,8 @@ type IStorageData = {
|
|||||||
* 1. 该类封装了 wxStorage 操作
|
* 1. 该类封装了 wxStorage 操作
|
||||||
* 2. 全异步获取无阻塞
|
* 2. 全异步获取无阻塞
|
||||||
* 3. 使用数据缓缓冲区,优化高频存取
|
* 3. 使用数据缓缓冲区,优化高频存取
|
||||||
* 4.
|
* 4. 如果全局范围内已存在莫键值 storage 的实例
|
||||||
|
* 则此实例将链接到已存在实例
|
||||||
*/
|
*/
|
||||||
class Storage<T extends IStorageData> {
|
class Storage<T extends IStorageData> {
|
||||||
|
|
||||||
@ -103,18 +112,41 @@ class Storage<T extends IStorageData> {
|
|||||||
/**
|
/**
|
||||||
* 缓存数据
|
* 缓存数据
|
||||||
*/
|
*/
|
||||||
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 等待列表
|
* cache 到 storage 等待列表
|
||||||
*/
|
*/
|
||||||
private saveWaiter:Waiter = new Waiter();
|
private saveWaiter:Waiter = new Waiter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存对象
|
||||||
|
*/
|
||||||
|
private cacheStorage:Storage<T> | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将数据从 cache 同步到 storage
|
* 将数据从 cache 同步到 storage
|
||||||
*/
|
*/
|
||||||
public async save():Promise<void> {
|
public async save():Promise<void> {
|
||||||
|
|
||||||
|
// 如果存在链接的实例
|
||||||
|
if (this.cacheStorage) return this.cacheStorage.save();
|
||||||
|
|
||||||
// 如果没有开始存储
|
// 如果没有开始存储
|
||||||
// 发起一次异步读取
|
// 发起一次异步读取
|
||||||
if(this.saveWaiter.state === StorageState.DONE)
|
if(this.saveWaiter.state === StorageState.DONE)
|
||||||
@ -150,6 +182,24 @@ class Storage<T extends IStorageData> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在缓存中搜索此键值的实例
|
||||||
|
*/
|
||||||
|
private findStorageCache(): boolean {
|
||||||
|
let { storage: storageMap } = getApp<IAppStorageParam>();
|
||||||
|
|
||||||
|
// 查找缓存
|
||||||
|
let storage = storageMap.get(this.key);
|
||||||
|
if (storage) {
|
||||||
|
this.cacheStorage = storage as Storage<T>;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 缓存此实例
|
||||||
|
storageMap.set(this.key, this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置全部数据
|
* 重置全部数据
|
||||||
*/
|
*/
|
||||||
@ -164,13 +214,25 @@ class Storage<T extends IStorageData> {
|
|||||||
/**
|
/**
|
||||||
* @param defaultData 键值默认数据
|
* @param defaultData 键值默认数据
|
||||||
*/
|
*/
|
||||||
public constructor(key:string, defaultData:T) {
|
public constructor(key:string, defaultData?:T) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.defaultData = defaultData;
|
this.defaultData = defaultData ?? {} as T;
|
||||||
this.StorageLogLabel = new LogLabel(
|
this.StorageLogLabel = new LogLabel(
|
||||||
`Storage:${ this.key }`, colorRadio(34, 230, 258)
|
`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<T>(this.key);
|
this.cache = wx.getStorageSync<T>(this.key);
|
||||||
|
|
||||||
@ -205,4 +267,4 @@ class Storage<T extends IStorageData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default Storage;
|
export default Storage;
|
||||||
export { Storage, StorageState, Waiter };
|
export { Storage, StorageState, Waiter, IAppStorageParam, IStorageData };
|
@ -15,6 +15,15 @@ implements Partial<ILifetime> {
|
|||||||
be: 2
|
be: 2
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let s2 = new Storage("test", {
|
||||||
|
be: 1,
|
||||||
|
aa: "abc"
|
||||||
|
});
|
||||||
|
|
||||||
|
s2.set("be", 4);
|
||||||
|
|
||||||
|
console.log(s, s2);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
s.set("be", 12);
|
s.set("be", 12);
|
||||||
}, 1000)
|
}, 1000)
|
||||||
@ -55,9 +64,7 @@ implements Partial<ILifetime> {
|
|||||||
}
|
}
|
||||||
}).request().wait({
|
}).request().wait({
|
||||||
success: (d) => console.log(d)
|
success: (d) => console.log(d)
|
||||||
}).wait({
|
})
|
||||||
success: (d) => console.log(d)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user