实现一个管理本地缓存过期的函数
封装 localStorage,实现带过期时间的本地缓存管理功能
问题
原生的 localStorage 只能永久存储数据,不支持设置过期时间。在实际开发中,我们经常需要为缓存数据设置有效期,过期后自动失效。本题要求实现一个带过期时间管理的本地缓存工具函数。
解答
class CacheStorage {
constructor(storage = localStorage) {
this.storage = storage;
}
/**
* 设置缓存
* @param {string} key - 缓存键名
* @param {any} value - 缓存值
* @param {number} expire - 过期时间(毫秒),不传则永久有效
*/
set(key, value, expire) {
const data = {
value,
expire: expire ? Date.now() + expire : null
};
try {
this.storage.setItem(key, JSON.stringify(data));
} catch (error) {
console.error('缓存设置失败:', error);
}
}
/**
* 获取缓存
* @param {string} key - 缓存键名
* @returns {any} 缓存值,过期或不存在返回 null
*/
get(key) {
try {
const item = this.storage.getItem(key);
if (!item) {
return null;
}
const data = JSON.parse(item);
// 检查是否过期
if (data.expire && Date.now() > data.expire) {
this.remove(key);
return null;
}
return data.value;
} catch (error) {
console.error('缓存读取失败:', error);
return null;
}
}
/**
* 删除缓存
* @param {string} key - 缓存键名
*/
remove(key) {
this.storage.removeItem(key);
}
/**
* 清空所有缓存
*/
clear() {
this.storage.clear();
}
/**
* 检查缓存是否存在且未过期
* @param {string} key - 缓存键名
* @returns {boolean}
*/
has(key) {
return this.get(key) !== null;
}
/**
* 清理所有过期缓存
*/
clearExpired() {
const keys = Object.keys(this.storage);
keys.forEach(key => {
try {
const item = this.storage.getItem(key);
if (item) {
const data = JSON.parse(item);
if (data.expire && Date.now() > data.expire) {
this.remove(key);
}
}
} catch (error) {
// 忽略解析错误的项
}
});
}
}
// 创建默认实例
const cache = new CacheStorage();
// 导出函数式 API
export const setCache = (key, value, expire) => cache.set(key, value, expire);
export const getCache = (key) => cache.get(key);
export const removeCache = (key) => cache.remove(key);
export const clearCache = () => cache.clear();
export const hasCache = (key) => cache.has(key);
export const clearExpiredCache = () => cache.clearExpired();
export default cache;
使用示例
// 示例 1: 基本使用
cache.set('username', 'zhangsan', 5000); // 5秒后过期
console.log(cache.get('username')); // 'zhangsan'
setTimeout(() => {
console.log(cache.get('username')); // null (已过期)
}, 6000);
// 示例 2: 存储对象数据
const userInfo = {
id: 1,
name: '张三',
age: 25
};
cache.set('userInfo', userInfo, 60 * 60 * 1000); // 1小时后过期
// 示例 3: 永久缓存(不设置过期时间)
cache.set('theme', 'dark');
console.log(cache.get('theme')); // 'dark'
// 示例 4: 检查缓存是否存在
if (cache.has('token')) {
console.log('用户已登录');
} else {
console.log('请先登录');
}
// 示例 5: 清理过期缓存
cache.set('temp1', 'data1', 1000);
cache.set('temp2', 'data2', 2000);
cache.set('permanent', 'data3'); // 永久
setTimeout(() => {
cache.clearExpired(); // 清理过期的 temp1 和 temp2
console.log(cache.get('permanent')); // 'data3' (仍然存在)
}, 3000);
// 示例 6: 使用函数式 API
import { setCache, getCache, removeCache } from './cache';
setCache('token', 'abc123', 24 * 60 * 60 * 1000); // 24小时
const token = getCache('token');
removeCache('token');
关键点
- 数据结构设计:将值和过期时间封装成对象存储,格式为
{ value, expire } - 过期判断:读取时检查
Date.now() > expire,过期则自动删除并返回 null - 异常处理:使用 try-catch 捕获 JSON 解析和存储异常,避免程序崩溃
- 灵活性:支持设置过期时间或永久存储(expire 为 null)
- 类封装:使用 class 封装,支持传入不同的 storage(localStorage/sessionStorage)
- API 完整性:提供 set、get、remove、clear、has 等完整的缓存操作方法
- 主动清理:提供 clearExpired 方法批量清理过期缓存,优化存储空间
- 类型支持:自动序列化和反序列化,支持存储对象、数组等复杂类型
目录