功能说明
查询不存在的数据时,如果每次都访问数据库,会增加延迟并放大缓存穿透风险。NegativeCache 同时缓存命中的值和未命中的空结果,并为每条记录设置 TTL,过期后重新查询。get 返回 hit 标记,value 为 null 表示负缓存命中,从而与真正未命中区分。
关键代码
构造时校验 TTL 为正数并允许注入时钟。get 未找到或已过期都返回 hit:false,过期记录会被删除;value 为 null 时只返回 hit:true。withNegativeCache 先查缓存,未命中时调用 loader,根据 null 结果写入负缓存或正常值。
const cached = cache.get(key);
if (cached.hit) return cached.value ?? null;
const value = await loader();
if (value === null) cache.setMiss(key);
else cache.setValue(key, value);
return value;
使用注意
负缓存会延迟新数据可见时间,TTL 应短于正常缓存。该实现只缓存 null 表示不存在,不缓存加载异常,避免把临时故障固化。键可以是任意类型,但应保持稳定。多实例之间不共享,生产环境可替换为 Redis。setValue 拒绝 null,防止语义混淆。
验证方式
断言首次查询调用 loader,第二次命中缓存不再调用。负缓存命中返回 null。TTL 到期后重新调用 loader。setValue 后 get 返回 hit 与值。ttlMs 为 0 抛 RangeError,setValue 传 null 抛 TypeError,loader 非函数抛 TypeError。