理解系列-localForage源码的降级策略

localForage 是什么

localForage 是一个 JavaScript 库,只需要通过简单类似 localStorage API 的异步存储来改进你的 Web 应用程序的离线体验。它能存储多种类型的数据,而不仅仅是字符串。

小知识:如果项目无需兼容 IE 浏览器,可以试试使用 yux-storage,代码 100 行左右,但可能兼容性不如localForage;

特点-降级缓存

数据储存回顾

  • cookie 大小 4kb,任何 cookie 大小超过限制都被忽略,且永远不会被设置
  • localStorage,虽然比 cookie 多,但是同样有上限(5M)左右
  • websql 使用简单,存储量大,兼容性差
  • indexDB api 多且繁琐,存储量大、高版本浏览器兼容性较好 >=250m

localForage 缓存

localForage 的出现就是采用降级缓存策略,进行缓存兼容,策略如下:

使用顺序:indexDB> websql>localStorage,localStorage是兜底的,因为兼容性几乎全覆盖:

localForage 包大小

未压缩30k左右(gzipped:9k左右),体积方面没啥问题

localForage 使用

js 复制代码
  // 通过 npm 安装:
  npm install localForage

  // 直接引用
  <script src="localForage.js"></script>
  <script>console.log('localForage is: ', localForage);</script>
js 复制代码
//获取存储
localForage
  .getItem('somekey')
  .then(function (value) {})
  .catch(function (err) {});

// 回调版本:
localForage.getItem('somekey', function (err, value) {});
js 复制代码
//储存数据
localForage
  .setItem('somekey', 'some value')
  .then(function (value) {})
  .catch(function (err) {});

// 不同于 localStorage,你可以存储非字符串类型
localForage
  .setItem('my array', [1, 2, 'three'])
  .then(function (value) {})
  .catch(function (err) {});
js 复制代码
//删除数据
localForage
  .removeItem('somekey')
  .then(function () {})
  .catch(function (err) {});

localForage 源码-降级策略

为了统一缓存方法,三大类型缓存都暴露一致的api

js 复制代码
var asyncStorage = {
    _driver: 'asyncStorage',
    _initStorage: _initStorage,
    _support: isIndexedDBValid(),
    iterate: iterate,
    getItem: getItem,
    setItem: setItem,
    removeItem: removeItem,
    clear: clear,
    length: length,
    key: key,
    keys: keys,
    dropInstance: dropInstance
};
var webSQLStorage = {
    _driver: 'webSQLStorage',
    _initStorage: _initStorage,
    _support: isWebSQLValid(),
    iterate: iterate,
    getItem: getItem,
    setItem: setItem,
    removeItem: removeItem,
    clear: clear,
    length: length,
    key: key,
    keys: keys,
    dropInstance: dropInstance
};
var localStorageWrapper = {
    _driver: 'localStorageWrapper',
    _initStorage: _initStorage,
    _support: isLocalStorageValid(),
    iterate: iterate,
    getItem: getItem,
    setItem: setItem,
    removeItem: removeItem,
    clear: clear,
    length: length,
    key: key,
    keys: keys,
    dropInstance: dropInstance
};

localForage类装载的api

js 复制代码
const OptionalDriverMethods = ['dropInstance'];

const LibraryMethods = [
    'clear',
    'getItem',
    'iterate',
    'key',
    'keys',
    'length',
    'removeItem',
    'setItem'
].concat(OptionalDriverMethods);

降级策略

在初始化时候,localForage已经根据浏览器支持情况,按照优先使用 indexDB,其次是 websql,最后是 localStorage顺序设置好。

js 复制代码
    //在定义驱动数组的时候,已经默认好顺序
    const DefaultDriverOrder = [
        DefaultDrivers.INDEXEDDB._driver,
        DefaultDrivers.WEBSQL._driver,
        DefaultDrivers.LOCALSTORAGE._driver
    ];
    //在设置驱动时候,已经通过
    setDriver(drivers, callback, errorCallback) {
        const supportedDrivers = this._getSupportedDrivers(drivers);
            ...省略无关代码
        const oldDriverSetDone =
            this._driverSet !== null
                ? this._driverSet.catch(() => Promise.resolve())
                : Promise.resolve();

        this._driverSet = oldDriverSetDone
            .then(() => {
                const driverName = supportedDrivers[0];//默认取驱动数组的第一个
                self._dbInfo = null;
                self._ready = null;

                return self.getDriver(driverName).then(driver => {
                    self._driver = driver._driver;
                    setDriverToConfig();
                    self._wrapLibraryMethodsWithReady();
                    self._initDriver = initDriver(supportedDrivers);
                });
            })
            .catch(() => {
                setDriverToConfig();
                const error = new Error('No available storage method found.');
                self._driverSet = Promise.reject(error);
                return self._driverSet;
            });
    }
    //获取用户环境支持的驱动
    _getSupportedDrivers(drivers) {
        const supportedDrivers = [];
        for (let i = 0, len = drivers.length; i < len; i++) {
            const driverName = drivers[i];
            if (this.supports(driverName)) {
                supportedDrivers.push(driverName);
            }
        }
        return supportedDrivers;
    }

上面的初始化策略会有一个问题,如果用户切换环境,比如从支持 indexDB 的浏览器切换到不支持 indexDB 的浏览器,那么就会造成缓存不可用。

js 复制代码
localforage.INDEXEDDB
localforage.WEBSQL
localforage.LOCALSTORAGE

//可以手动设置到对应的缓存驱动
localforage.setDriver(localforage.LOCALSTORAGE);

相关文档:

localForage文档

相关推荐
随云632几秒前
WebGL编程指南之着色器语言GLSL ES(入门GLSL ES这篇就够了)
前端·webgl
寻找09之夏1 小时前
【Vue3实战】:用导航守卫拦截未保存的编辑,提升用户体验
前端·vue.js
非著名架构师1 小时前
js混淆的方式方法
开发语言·javascript·ecmascript
多多米10052 小时前
初学Vue(2)
前端·javascript·vue.js
敏编程2 小时前
网页前端开发之Javascript入门篇(5/9):函数
开发语言·javascript
柏箱2 小时前
PHP基本语法总结
开发语言·前端·html·php
新缸中之脑2 小时前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
hmz8562 小时前
最新网课搜题答案查询小程序源码/题库多接口微信小程序源码+自带流量主
前端·微信小程序·小程序
看到请催我学习2 小时前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript
blaizeer3 小时前
深入理解 CSS 浮动(Float):详尽指南
前端·css