首页 > 其他分享 >[js函数] storageManager

[js函数] storageManager

时间:2023-02-16 19:33:26浏览次数:35  
标签:const 函数 persistConfig storageManager js storageData storageName path watcher

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
}

  

 

标签:const,函数,persistConfig,storageManager,js,storageData,storageName,path,watcher
From: https://www.cnblogs.com/lhp2012/p/17128029.html

相关文章

  • 普通生成函数学习笔记
    现在我们考虑有一个序列\((a_1,a_2,a_3,\cdots,a_n,\cdots)\)。我们将这个序列作为形式幂级数\(A(x)=\sum_{n\ge0}{a_{n}x^n}\)的常数项序列。\(A(x)\)就是序列\(\{a......
  • python处理json
    importjson#str----->jsonstr='{"name":"御姐","age":18}'j=json.loads(str)print(j)print(type(j))#str----->json------>strstr='{"name":"御姐",......
  • Python sorted函数及用法
    orted()作为 Python 内置函数之一,其功能是对序列(列表、元组、字典、集合、还包括字符串)进行排序。sorted()函数的基本语法格式如下:list=sorted(iterable,key=None,......
  • 解析MYSQL建表语句,生成表结构的JSON
    根据建表语句解析表结构,并将表结构解析为JSON。根据MYSQL的建表语句,建表语句:CREATETABLE`TEST`(`ID`varchar(56)NOTNULL,`CREAETE_TIME`datetimeN......
  • 如何查看库函数实现的某些函数(strlen,strcmp,strcpy等)
    我们拿strlen()作为举例(编译环境为:VS2022)strlen()引用的头文件为string.h,如下进行操作ps:打开strlen.c文件便可以看到库函数对于strlen()的实现,若要搜索其他在库......
  • MATLAB 一些常用的处理数据函数
    记录一些简单的功能方便及时调出来看,并附上一些参考链接,这样就不用总是重复查了......多学一个就多补充一个。统计数组中指定元素数量参考链接:https://www.ilovematl......
  • nestjs微信小程序登录授权
    前言nestjs官方文档是英文,太难搞了,摸索了两天,把经验记下来。以后备用目录结构|--src//项目根目录|--modules//模块比如用户模块,商品模块|--app//入口模......
  • QT中调用不同cpp文件的变量或者函数
    有时候会遇到一个问题,在QT中,需要使用另一个文件的函数或者对象,但是没办法直接使用。一般是在其他类中想使用主类中的函数或者变量方法1:在需要使用的文件中声明这个类, ......
  • 原生 js 渐变图例
    https://codepen.io/hihust-knighterrant/pen/YzOPLgB渐变色图例<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"c......
  • js逆向中常见加密/解密算法实现(js、python)
    常见加密、解密算法实现(JS、python)base64NodejsconstCryptoJS=require('crypto-js')//加密letpwd='密码'letb64_pwd=Buffer.from(pwd).toString('b......