[js函数] storageManager
import _get from 'lodash.get';
import _set from 'lodash.set';
import _debounce from 'lodash.debounce';
import {shallowEqual} from "./shallow-equal"; const IS_STORAGE_INITIALIZED = '$$IS_STORAGE_INITIALIZED$$'; interface PersistConfig {
save: (storageName: string, storageData: any) => void;
load: (storageName: string) => Promise<any>;
} type WatcherFn = (nextValue: any, preValue: any, storage: Storage) => void; interface Watcher {
path: string,
watcher: WatcherFn,
preValue: any
} class Storage {
private readonly storageName: string;
private storageData: Record<string, any>;
private watcherList: Watcher[];
private persistConfig: PersistConfig | null;
private readonly persistStorageFn: any; constructor(storageName: string) {
this.storageName = storageName;
this.storageData = {};
this.watcherList = []; // {path, watcher, preValue}
this.persistConfig = null; // {save:(storageName,storageData)=>{}, load:(storageName)=>{}}
this.persistStorageFn = _debounce(() => {
this.persistStorage();
}, 100);
setTimeout(() => {
this.persistStorageInit();
}, 1);
} setPersistConfig(persistConfig: PersistConfig) {
this.persistConfig = persistConfig;
} initStorageData(storageData: Record<string, any>) {
this.storageData = storageData;
this.storageData[IS_STORAGE_INITIALIZED] = true;
this.notifyWatcher();
} getValue(path: string) {
return _get(this.storageData, path);
} setValue(path: string, value: any) {
_set(this.storageData, path, value);
this.notifyWatcher();
this.persistStorageFn()
} watch(path: string, watcher: WatcherFn) {
if (typeof watcher !== "function") {
throw 'watcher must function';
}
this.watcherList.push({path, watcher, preValue: undefined});
} unwatch(path: string, watcher: WatcherFn) {
this.watcherList = this.watcherList.filter((obj) => {
return obj.path !== path && obj.watcher !== watcher;
});
} notifyWatcher() {
const watcherList = this.watcherList || [];
for (let i = 0; i < watcherList.length; i++) {
const {path, watcher, preValue} = watcherList[i];
const nextValue = this.getValue(path);
if (!shallowEqual(nextValue, preValue)) {
watcher(nextValue, preValue, this);
watcherList[i].preValue = nextValue;
}
}
} persistStorage() {
const persistConfig = this.persistConfig;
if (!persistConfig) {
return;
}
const {save} = persistConfig;
save(this.storageName, this.storageData);
} persistStorageInit() {
const persistConfig = this.persistConfig;
if (!persistConfig) {
this.initStorageData({});
return;
} const {load} = persistConfig;
load(this.storageName).then((storageData) => {
if (storageData && typeof storageData === "object") {
this.initStorageData(storageData);
} else {
this.initStorageData({});
}
}, () => {
this.initStorageData({});
});
} } class StorageManager { private storageMap: Record<string, Storage> = {}; getStorage(storageName: string) {
if (!this.storageMap[storageName]) {
this.storageMap[storageName] = new Storage(storageName);
}
return this.storageMap[storageName];
} } const storageManager = new StorageManager(); export {
storageManager,
IS_STORAGE_INITIALIZED
}
import localforage from '@ali/ascp-shared-local-forage' /**
* 使用 localStorage 存储
*/
const localStoragePersist = {
save: (storageName, storageData) => {
localStorage.setItem(storageName, JSON.stringify(storageData));
},
load: (storageName) => {
return new Promise((resolve) => {
const str = localStorage.getItem(storageName);
if (str) {
resolve(JSON.parse(str))
} else {
resolve(null);
}
})
}
} /**
* 使用 localforage 存储
*/
const localForagePersist = {
save: (storageName, storageData) => {
localforage.setItem(storageName, storageData);
},
load: (storageName) => {
return localforage.getItem(storageName);
}
}; export {
localStoragePersist,
localForagePersist
}
import {useEffect, useState} from 'react';
import {storageManager} from "../utils/storage";
function useStorageValue(storageName, persistConfig, path) {
const storage = storageManager.getStorage(storageName);
storage.setPersistConfig(persistConfig)
const [value, setValue] = useState(() => {
return storage.getValue(path);
});
useEffect(() => {
const watcher = (nowValue) => {
setValue(nowValue);
};
storage.watch(path, watcher);
return () => {
storage.unwatch(path, watcher);
}
}, [storageName, path]);
return value;
}
export {
useStorageValue
}
[js函数] storageManager的更多相关文章
- 3.3 js函数
1.函数语法: 函数声明的方式:function 函数名(参数1,参数2-){//函数体;}函数调用:函数名(参数1,参数2-); 函数内不一定都指定返回值. 如果需要指定返回值,可用 return ...
- Js函数function基础理解
正文:我们知道,在js中,函数实际上是一个对象,每个函数都是Function类型的实例,并且都与其他引用类型一样具有属性和方法.因此,函数名实际上是指向函数对象的指针,不与某个函数绑定.在常见的两种定 ...
- js函数表达式和函数声明的区别
我们已经知道,在任意代码片段外部添加包装函数,可以将内部的变量和函数定义"隐 藏"起来,外部作用域无法访问包装函数内部的任何内容. 例如: var a = 2; function ...
- 通用js函数集锦<来源于网络> 【二】
通用js函数集锦<来源于网络> [二] 1.数组方法集2.cookie方法集3.url方法集4.正则表达式方法集5.字符串方法集6.加密方法集7.日期方法集8.浏览器检测方法集9.json ...
- 通用js函数集锦<来源于网络/自己> 【一】
通用js函数集锦<来源于网络/自己>[一] 1.返回一个全地址2.cookie3.验证用户浏览器是否是微信浏览器4.验证用户浏览器是否是微博内置浏览器5.query string6.验证用 ...
- 100多个基础常用JS函数和语法集合大全
网站特效离不开脚本,javascript是最常用的脚本语言,我们归纳一下常用的基础函数和语法: 1.输出语句:document.write(""); 2.JS中的注释为//3.传统 ...
- JS函数
1.document.write(""); 输出语句2.JS中的注释为//3.传统的HTML文档顺序是:document->html->(head,body)4.一个浏 ...
- js函数和运算符
函数是由事件驱动或者它被调用时执行可重复使用的代码块. <script> function myFunction(){ Alert(“hello World!”): } </scri ...
- JavaScript学习03 JS函数
JavaScript学习03 JS函数 函数就是包裹在花括号中的代码块,前面使用了关键词function: function functionName() { 这里是要执行的代码 } 函数参数 函数的 ...
- JSF页面中使用js函数回调后台bean方法并获取返回值的方法
由于primefaces在国内使用的并不是太多,因此,国内对jsf做系统.详细的介绍的资料很少,即使有一些资料,也仅仅是对国外资料的简单翻译或者是仅仅讲表面现象(皮毛而已),它们的语句甚至还是错误的, ...
随机推荐
- NOIP 模拟赛 左右横跳
\(\text{Problem}\) 大意就是优化这样一个 \(dp\) \[f_{i}=\max f[j]+(i-j) \cdot (i-j-1) \] \(L[i] \le j < i,n\ ...
- JZOJ 3226. 【HBOI2013】ALO
题目 网上自己搜 解析 区间异或很容易想到可持久化字典树 但本题的关键是如何高效率求出以某个数为区间最大值时这个区间的范围 依题我们知道区间最长可到比它第二大的位置(开区间) 所以我们如果能找到每个数 ...
- JZOJ 5353. 【NOIP2017提高A组模拟9.9】村通网
题目 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里每座建筑都连上互联网,方便未来随时随地网购农药. 他的农庄很大,有N 座建筑,但地理位置偏僻,网络信号很差. 一座建筑 ...
- 18 网路进阶设定:Bridge、LACP、VLAN
18 网路进阶设定:Bridge.LACP.VLAN 18.1 建立第二网路桥接装置(Bridge) 在预设安装完的情况下,PVE会使用其中一个连接埠桥接至[vmbr0]这个预设的网路桥接装置,所有的 ...
- pat乙级1016 部分A+B
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> ...
- 使用AJAX绑定点击事件将接口值返回渲染到指定位置
AJAX 是局部的刷新或者叫做无刷新技术 首先是js部分,这里注意不紧要引入express模块,还需要把cors模块也引入 在下面添加了判断,用来判断所取得的随机值是否在0.5以上 接下来是HTML部 ...
- C# 元组类型和元组文本
从 C# 7.0 开始,可以使用元组类型和元组文本轻松实现此目的. 元组类型定义元 组元素的数据类型. 元组文本提供返回的元组的实际值. 在下面的示例中, (string, string, strin ...
- pytest框架增加log打印(包括pytest的执行结果、自定义的log信息)
前言: 之前同事在跑脚本的时候报错了,发现没法把需要的log信息打印出来,我这边定位问题比较麻烦,所以增加了log的打印.这个问题之前已经处理过了,本来以为是小问题,结果今天又要用到这个小技巧的时候居 ...
- Java中Set里remove详解
例如 1 HashSet set = new HashSet(); 2 Person p1 = new Person(1001,"AA"); 3 Person p2 = new P ...
- io流转换为Multipart文件
io流转换为Multipart文件 个人的话是运用到了minio文件服务器保存文件,前端(vue)异步上传文件后,由于要提升用户体验效果,先上传文件到后台服务器,返回视频在文件服务器的link()参数 ...