运用惰性删除和定时删除实现可过期的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空间的浪费。
每隔一秒执行一次定时删除,操作如下:
- 随机测试20个设置了过期时间的key。
- 删除所有发现的已过期的key。
- 若删除的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 || {}));
完整源码及使用示例
完整源码及使用示例已上传到我的GitHub(https://github.com/heihaozi/LocalStorageCache)上,感谢各位小伙伴的Star和Fork。
总结
一种策略可能会有自己的缺点,为了规避相应的缺点,我们可以合理运用多种策略,扬长避短就得到接近完美的解决方案。
微信公众号:万猫学社
微信扫描二维码
获得更多Java技术干货

运用惰性删除和定时删除实现可过期的localStorage缓存的更多相关文章
- Window bat expdp 定时任务逻辑备份 定时删除N天前的旧文件
点击进入:Linux shell crontab expdp 定时任务逻辑备份 定时删除旧文件 首先建一个备份数据库用批处理文件,内容如下: rem expdp sz set sz_file=SZ_% ...
- Linux shell crontab expdp 定时任务逻辑备份 定时删除旧文件
点击进入:Window bat expdp 定时任务逻辑备份 定时删除N天前的旧文件 创建sh脚本 [oracle@localhost ~]$ vi logicbackup.sh 添加脚本内容 #!/ ...
- powershell 定时删除脚本
powershell 定时删除脚本 $today=Get-Date #"今天是:$today" #昨天 #"昨天是:$($today.AddDays(-1))" ...
- mongodb系列~mongodb定时删除数据
一 简介:本文介绍创建自动删除数据的TTL索引 二 目的 定时删除数据三 创建方法 db.collection.createIndex(keys, options) options: ex ...
- 【转】ElasticSearch之定时删除数据
有的时候我们在使用ES时,由于资源有限或业务需求,我们只想保存最近一段时间的数据,所以有如下脚本可以定时删除数据 delete_es_by_day.sh #!/bin/sh # example: in ...
- 【shell】定时删除DB2表数据
使用db2的时候,有时候需要对表数据进行删除,防止数据太多,造成数据库空间满了 以下是一个定时删除表tmp,tm1中id为1的数据的脚本 #!/bin/sh ##------------------- ...
- Linux中定时删除超过指定大小的文件夹
背景: 开发环境总是动不动就没有空间了, 大部分都是debug日志.所以有必要在日志很疯狂的时候,删除不必要的日志. 思路:一. 书写删除日志文件脚本: 定时任务执行. 但是有时候的日志是需要保存用 ...
- Windows 定时删除指定路径下N天前的日志文件
Windows 定时删除指定路径下N天前的日志文件 Windows 下bat脚本文件的内容为 1. 删除指定路径下5天前的所有文件 @echo off set SrcDir=E:\WORK\Git s ...
- mongodb定时删除数据(索引删除)
一 简介:本文介绍创建自动删除数据的TTL索引 二 目的 定时删除数据三 创建方法 db.collection.createIndex(keys, options) options: ex ...
随机推荐
- C# 基础知识系列- 16 开发工具篇
0. 前言 这是C# 基础知识系列的最后一个内容讲解篇,下一篇是基础知识-实战篇.这一篇主要讲解一下C#程序的结构和主要编程工具. 1. 工具 工欲善其事必先利其器,在实际动手之前我们先来看看想要编写 ...
- 搬东西 dp
搬东西 现有n个扁担以及一辆货车,扁担一次挑两个货物,货车可以装K个货物,货车只能运送一次货物. 现在qwb要把总共2n+k个货物搬到某个地方.现在qwb想选K个货物让货车先运走,然后剩下的2n个货物 ...
- spring学习笔记(九)事务学习(上)
前述 这段时间在工作中碰到一个事务相关的问题.先说下这个问题的场景,我们是一个商城项目,正在开发优惠券模块,现在有一个需求是需要批量领取优惠券,而且在领券时,其中一张领取失败不能影响其他符合要求的 ...
- Owin Katana 的底层源码分析
最近看了一下开源项目asp.net katana,感觉公开的接口非常的简洁优雅,channel 9 说是受到node.js的启发设计的,Katana是一个比较老的项目,现在已经整合到asp.net c ...
- [CodeForces 300D Painting Square]DP
http://codeforces.com/problemset/problem/300/D 题意:每一次操作可以选一个正方形,令边长为n,如果n为奇数那么可以从中间画一个十字,分成4个大小相等的边长 ...
- [csu1392]YY一下
题意:给定x,求有多少个10^8以内的数满足这个数乘以x以后,最高位到了最低位.设最高位的数字和剩余长度,列等式推理即可. #pragma comment(linker, "/STACK:1 ...
- Centos 编译带调试信息的libevent
libevent编译过程 查看libevent文档即可 解决cmake编译出来的可执行文件没有调试信息(该方法未实验,暂时对cmake不熟悉) SET(CMAKE_BUILD_TYPE "D ...
- Centos ps命令
输出格式(ps -aux) USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND VSZ:占用的虚拟内存大小() RSS: COMMAND: 执 ...
- java ->会话技术Cookie&Session
会话技术Cookie&Session 会话技术简介 存储客户端的状态 由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪里?因为Http协议是无状态的,也就是说每个客户 ...
- Java线程的几种可用状态
1. 新建( new ):新创建了一个线程对象. 2. 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start()方法.该状态的线程位于可运行线程 ...