javascript可用闭包封装带ttl的缓存,通过闭包内维护value与expiresat实现自动过期;支持单值缓存和基于json.stringify(args)键的多值缓存,过期时删除对应项。

JavaScript 中可以用闭包封装缓存数据与过期时间,通过每次访问时检查时间戳来实现“自动过期”的缓存失效机制。核心是把缓存值和它的过期时间(如 Date.now() + ttl)一起保存在闭包内,读取时判断是否已超时。
基础结构:带 TTL 的缓存闭包
用一个工厂函数返回带缓存能力的函数,内部维护 cachedValue 和 expiresAt:
function createCachedFn(fn, ttlMs = 5000) {
let cachedValue = null;
let expiresAt = 0;
return function(...args) {
const now = Date.now();
// 缓存未过期,直接返回
if (now
用法示例:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
const expensiveCalc = () => {
console.log('执行耗时计算...');
return Math.random();
};
const cachedCalc = createCachedFn(expensiveCalc, 2000);
console.log(cachedCalc()); // 打印"执行耗时计算...",返回随机数
console.log(cachedCalc()); // 不打印,直接返回上次结果(2秒内)
// 等待 2s+ 后再调用,会重新计算
支持参数依赖的缓存键(避免误共享)
上面版本对所有调用共用一份缓存,不区分参数。若需按参数缓存(如 getUser(1) 和 getUser(2) 独立缓存),可用 Map 存储多个键值对,并生成简单缓存键:
- 用
JSON.stringify(args)作为 key(仅适用于参数可序列化且无函数/undefined/null) - 每个 key 对应自己的
{ value, expiresAt }对象 - 过期检查在 get 时进行,过期则删除该 key
function createCachedFnByKey(fn, ttlMs = 5000) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
const now = Date.now();
const entry = cache.get(key);
if (entry && now
手动清理与调试支持
实际使用中常需要主动清空缓存(如数据更新后)或查看状态。可在闭包内暴露方法:
- 添加
.clear()方法清空全部缓存 - 添加
.has(key)或.size方便监控 - 注意:这些方法需绑定到返回的函数上,或返回一个含方法的对象
function createCachedFnWithControl(fn, ttlMs = 5000) {
const cache = new Map();
const cachedFn = function(...args) {
const key = JSON.stringify(args);
const now = Date.now();
const entry = cache.get(key);
if (entry && now cache.clear();
cachedFn.size = () => cache.size;
cachedFn.has = (key) => {
const k = JSON.stringify(key);
const entry = cache.get(k);
return entry && Date.now()
注意事项与边界情况
这类闭包缓存轻量但有局限,使用时需留意:
-
时间精度问题:
Date.now()在某些低功耗设备或后台标签页可能不精确,关键场景建议用performance.now()(需配合首次调用时间基准) - 内存泄漏风险:Map 缓存持续增长,建议加最大容量限制 + LRU 驱逐逻辑(如用 lru-cache 替代)
- 异步函数处理:上述只适合同步函数;如缓存 Promise,需缓存整个 Promise 实例并注意拒绝状态不会自动重试
-
引用类型参数:
JSON.stringify([{id:1}])和JSON.stringify([{id:1}])相等,但对象引用不同——只要结构一致即可,这是预期行为
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










