美文网首页
运用惰性删除和定时删除实现可过期的localStorage缓存

运用惰性删除和定时删除实现可过期的localStorage缓存

作者: 万猫学社 | 来源:发表于2022-03-08 08:47 被阅读0次

    localStorage简介

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

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

    localStorage方法

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

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

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

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

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

    localStorage.removeItem('name');
    

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

    localStorage.clear();
    

    可过期的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。为了弥补这样缺点,我们引入另一种清理过期缓存的策略。

    定时删除

    定时删除是指,每隔一段时间执行一次删除操作,并通过限制删除操作执行的次数和频率,来减少删除操作对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。

    总结

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


    竟然已经看到这里了,你我定是有缘人,留下你的点赞关注,他日必成大器。

    相关文章

      网友评论

          本文标题:运用惰性删除和定时删除实现可过期的localStorage缓存

          本文链接:https://www.haomeiwen.com/subject/aizorrtx.html