Map实现前端缓存的核心是将参数序列化为唯一键存取结果:支持任意类型键,推荐JSON.stringify生成键;需处理属性顺序、不可序列化值;可封装通用memoize函数,兼容同步/异步,配合清理与TTL策略。

用 Map 实现前端缓存(Memoization)的核心是:把函数的参数组合转为唯一键,将计算结果存入 Map,后续相同输入直接返回缓存值,避免重复执行。
用 Map 构建带参数序列化键的缓存
Map 支持任意类型作键(包括对象、数组),比 Object 更适合缓存多参数函数。关键是把多个参数转为可比较的键——推荐用 JSON.stringify(适用于参数可序列化)或用 Array.from(arguments) + JSON.stringify 包装:
- 简单场景(参数全是基础类型或普通对象):
const key = JSON.stringify(args) - 需支持函数、undefined、Symbol 等不可序列化值时,改用
Map嵌套结构或自定义键生成器(如用WeakMap缓存对象参数本身) - 注意:
{a:1, b:2}和{b:2, a:1}序列化后不同,若需忽略属性顺序,应先排序 key 再 stringify
封装通用 memoize 工具函数
写一个高阶函数,接收原函数和可选的键生成器,返回缓存版函数:
function memoize(fn, getKey = (...args) => JSON.stringify(args)) {
const cache = new Map();
return function(...args) {
const key = getKey(...args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
使用示例:
const expensiveCalc = (a, b) => { /* 模拟耗时计算 */ return a * b + Date.now(); };
const cachedCalc = memoize(expensiveCalc);
console.log(cachedCalc(2, 3)); // 执行并缓存
console.log(cachedCalc(2, 3)); // 直接返回缓存值
处理异步函数与 Promise 缓存
对 async 函数,缓存的是 Promise 实例本身(不是 await 后的结果),避免重复发起请求:
- 直接缓存 Promise:下次调用相同参数时,返回同一个未 resolve 的 Promise(适合防重复请求)
- 若要缓存 resolved 值,需在 Promise settle 后再 set,但要注意错误情况——建议用
try/catch或.catch()存储 rejected 状态 - 简单做法:缓存 Promise 并共享,不额外处理状态,由调用方统一 await
缓存清理与生命周期控制
Map 不自动淘汰,需按需管理:
- 手动清除:
cache.clear()或cache.delete(key) - 设置最大容量:在
set前检查cache.size,超出则cache.delete(cache.keys().next().value)(FIFO) - 结合时间戳实现 TTL:每个 value 存为
{ data, timestamp },get 时判断是否过期 - 对依赖外部状态(如用户登录态、配置)的缓存,可在状态变更时主动清空
不复杂但容易忽略:键的稳定性决定缓存是否生效;避免在闭包中意外修改参数对象导致键不一致;生产环境建议加缓存命中率统计便于优化。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











