如何让Lodash _.memoize包裹的函数支持跳过缓存获取最新数据?
解决方案
可以基于_.memoize实现该需求,以下是两种常用实现方案,可根据业务场景选择:
方案1:手动清除指定缓存(推荐,无冗余缓存)
逻辑说明:当传入cached: false时,先删除对应参数的历史缓存,再执行请求,新请求的结果会自动更新到缓存中,后续正常调用依然可以命中缓存。
import { memoize } from "lodash"; const _getUserPost = memoize( async (userId, postId, options = { cached: true }) => { const postRef = firestore .collection("posts") .doc(userId) .collection("userPosts") .doc(postId); const postDoc = await postRef.get(); // 原有业务逻辑不变 return parseUserPost(postDoc); }, // 缓存key生成逻辑不变,仅关联userId和postId (userId, postId) => `[${userId},${postId}]` ); // 对外暴露的封装方法 export const getUserPost = async (userId, postId, options = { cached: true }) => { if (!options.cached) { // 生成对应缓存key,删除旧缓存 const cacheKey = `[${userId},${postId}]`; delete _getUserPost.cache[cacheKey]; } return _getUserPost(userId, postId, options); }
调用方式:
- 正常走缓存:
await getUserPost("raul", "postId") - 跳过缓存拉取最新数据:
await getUserPost("raul", "postId", { cached: false })
方案2:缓存key关联缓存控制参数
如果不需要将跳过缓存请求的结果更新到公共缓存,可直接修改resolver逻辑,把cached参数纳入缓存key生成规则,当cached为false时生成唯一不重复的key,自然不会命中历史缓存。
import { memoize } from "lodash"; export const getUserPost = memoize( async (userId, postId, options = { cached: true }) => { // 原有请求逻辑不变 const postRef = firestore .collection("posts") .doc(userId) .collection("userPosts") .doc(postId); const postDoc = await postRef.get(); return parseUserPost(postDoc); }, (userId, postId, options = { cached: true }) => { if (!options.cached) { // 追加时间戳和随机值保证key永远唯一,不会命中缓存 return `[${userId},${postId}]-${Date.now()}-${Math.random()}`; } return `[${userId},${postId}]`; } );
注意:该方案每次传cached: false的请求结果都会存入缓存,会占用额外内存,仅适合请求频次极低的场景。
内容的提问来源于stack exchange,提问作者Raul
相关产品推荐
相关产品推荐

