JavaScript缓存异常:更新单个节点致所有Last_Accessed_Time变更
问题分析与解决
问题根源
你的代码并没有在调用put()更新单个节点时修改所有节点的last_Accessed_Time,出现误解的原因主要有两点:
Date.now()的精度限制:Date.now()返回毫秒级时间戳,当代码连续快速执行时,多次调用会返回相同数值。你的测试代码中,前三次put和第四次更新key1的put几乎在同一毫秒内完成,导致所有节点时间戳看起来完全一致。控制台输出的惰性求值特性:部分浏览器或Node.js控制台输出对象时采用惰性求值——展开对象查看细节时,显示的是对象当前状态而非调用
console.log()时的状态。不过在你的场景中,核心问题还是时间戳精度导致的视觉混淆。
验证方法
你可以通过以下方式验证只有目标节点的时间被更新:
- 在每次
put调用之间增加微小延迟,确保时间戳不同:const cache = new CacheGenerator(3); cache.put("key1", "hokaido", 10); setTimeout(() => cache.put("key2", "tokyo", 20), 10); setTimeout(() => cache.put("key3", "osaka", 30), 20); setTimeout(() => { cache.put("key1", "sapporo", 40); // 用JSON序列化输出快照,避免惰性求值 console.log(JSON.stringify(Array.from(cache.cache.entries()), null, 2)); }, 30); - 改用更高精度的
performance.now()替代Date.now(),它能提供微秒级时间戳,即使快速执行也会有不同数值:// 将代码中所有Date.now()替换为performance.now() node.last_Accessed_Time = performance.now();
关于JSON.parse(JSON.stringify(...))的解释
直接用console.log()输出对象时,控制台保存的是对象引用而非快照。如果后续代码修改了对象,展开控制台输出时可能看到修改后的状态。用JSON.stringify()将对象序列化为字符串,再用JSON.parse()解析回来,就能得到调用时刻的对象快照,确保你看到的是执行console.log()时的真实状态。例如:
console.log(JSON.parse(JSON.stringify(Array.from(cache.cache.entries()))));
代码优化建议
如果希望缓存的访问时间更精准,推荐使用performance.now();同时在测试时,要么增加延迟,要么用序列化的方式输出对象快照,避免因时间精度或控制台特性导致的误解。
内容的提问来源于stack exchange,提问作者Norman Yang
相关产品推荐
相关产品推荐

