zoukankan      html  css  js  c++  java
  • 运用惰性删除和定时删除实现可过期的localStorage缓存

    localStorage简介

    使用localStorage可以在浏览器中存储键值对的数据。经常被和localStorage一并提及的是sessionStorage,它们都可以在当浏览器中存储键值对的数据。但是它们之间的区别是:存储在localStorage的数据可以长期保留;而当页面会话结束(也就是当页面被关闭)时,存储在sessionStorage的数据会被清除。

    另外需要注意的是,localStorage中的键值对总是以字符串的形式存储,并且只能访问当前域名下的数据,不能跨域名访问。

    欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

    localStorage方法

    可以通过setItem方法增加了一个键值对数据,比如:

    localStorage.setItem('name', 'OneMore');
    

    如果该键已经存在,那么该键对应的值将被覆盖。还可以使用getItem方法读取对应键的值数据,比如:

    var name = localStorage.getItem('name');
    

    可以使用removeItem方法移除对应的键,比如:

    localStorage.removeItem('name');
    

    也可以使用clear方法移除当前域名下所有的键值对数据,比如:

    localStorage.clear();
    

    欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

    可过期的localStorage缓存

    正如上面所提到的,localStorage只能用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除。所以要实现可过期的localStorage缓存的中重点就是:如何清理过期的缓存?

    惰性删除

    惰性删除是指,某个键值过期后,该键值不会被马上删除,而是等到下次被使用的时候,才会被检查到过期,此时才能得到删除。我们先来简单实现一下:

    var lsc = (function (self) {
        var prefix = 'one_more_lsc_'
        /**
         * 增加一个键值对数据
         * @param key 键
         * @param val 值
         * @param expires 过期时间,单位为秒
         */
        self.set = function (key, val, expires) {
            key = prefix + key;
            val = JSON.stringify({'val': val, 'expires': new Date().getTime() + expires * 1000});
            localStorage.setItem(key, val);
        };
        /**
         * 读取对应键的值数据
         * @param key 键
         * @returns {null|*} 对应键的值
         */
        self.get = function (key) {
            key = prefix + key;
            var val = localStorage.getItem(key);
            if (!val) {
                return null;
            }
            val = JSON.parse(val);
            if (val.expires < new Date().getTime()) {
                localStorage.removeItem(key);
                return null;
            }
            return val.val;
        };
        return self;
    }(lsc || {}));
    

    上述代码通过惰性删除已经实现了可过期的localStorage缓存,但是也有比较明显的缺点:如果一个key一直没有被用到,即使它已经过期了也永远存放在localStorage。为了弥补这样缺点,我们引入另一种清理过期缓存的策略。

    欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

    定时删除

    定时删除是指,每隔一段时间执行一次删除操作,并通过限制删除操作执行的次数和频率,来减少删除操作对CPU的长期占用。另一方面定时删除也有效的减少了因惰性删除带来的对localStorage空间的浪费。

    每隔一秒执行一次定时删除,操作如下:

    1. 随机测试20个设置了过期时间的key。
    2. 删除所有发现的已过期的key。
    3. 若删除的key超过5个则重复步骤1,直至重复500次。

    具体实现如下:

    var lsc = (function (self) {
        var prefix = 'one_more_lsc_'
        var list = [];
        //初始化list
        self.init = function () {
            var keys = Object.keys(localStorage);
            var reg = new RegExp('^' + prefix);
            var temp = [];
            //遍历所有localStorage中的所有key
            for (var i = 0; i < keys.length; i++) {
            	//找出可过期缓存的key
                if (reg.test(keys[i])) {
                    temp.push(keys[i]);
                }
            }
            list = temp;
        };
        self.init();
        self.check = function () {
            if (!list || list.length == 0) {
                return;
            }
            var checkCount = 0;
            while (checkCount < 500) {
                var expireCount = 0;
                //随机测试20个设置了过期时间的key
                for (var i = 0; i < 20; i++) {
                    if (list.length == 0) {
                        break;
                    }
                    var index = Math.floor(Math.random() * list.length);
                    var key = list[index];
                    var val = localStorage.getItem(list[index]);
                    //从list中删除被惰性删除的key
                    if (!val) {
                        list.splice(index, 1);
                        expireCount++;
                        continue;
                    }
                    val = JSON.parse(val);
                    //删除所有发现的已过期的key
                    if (val.expires < new Date().getTime()) {
                        list.splice(index, 1);
                        localStorage.removeItem(key);
                        expireCount++;
                    }
                }
                //若删除的key不超过5个则跳出循环
                if (expireCount <= 5 || list.length == 0) {
                    break;
                }
                checkCount++;
            }
        }
        //每隔一秒执行一次定时删除
        window.setInterval(self.check, 1000);
        return self;
    }(lsc || {}));
    

    完整源码及使用示例

    完整源码及使用示例已上传到我的GitHubhttps://github.com/heihaozi/LocalStorageCache)上,感谢各位小伙伴的Star和Fork。

    总结

    一种策略可能会有自己的缺点,为了规避相应的缺点,我们可以合理运用多种策略,扬长避短就得到接近完美的解决方案。

    微信公众号:万猫学社

    微信扫描二维码

    获得更多Java技术干货

  • 相关阅读:
    java 在线网络考试系统源码 springboot mybaits vue.js 前后分离跨域
    springboot 整合flowable 项目源码 mybiats vue.js 前后分离 跨域
    flowable Springboot vue.js 前后分离 跨域 有代码生成器 工作流
    Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    java 企业 网站源码 后台 springmvc SSM 前台 静态化 代码生成器
    java 进销存 商户管理 系统 管理 库存管理 销售报表springmvc SSM项目
    基于FPGA的电子计算器设计(中)
    基于FPGA的电子计算器设计(上)
    FPGA零基础学习:SPI 协议驱动设计
    Signal tap 逻辑分析仪使用教程
  • 原文地址:https://www.cnblogs.com/heihaozi/p/13023438.html
Copyright © 2011-2022 走看看