promise本身不自带缓存能力,但可通过map以请求参数为key缓存promise实例实现结果复用;需序列化参数生成唯一key,缓存promise而非值以支持链式调用,失败时可选择清除缓存,实际应用中常加入ttl过期、强制刷新及易变状态处理。

Promise 本身不自带缓存能力,但可以通过封装逻辑,在首次请求后把结果保存起来,后续调用直接返回已解析的 Promise,从而实现异步请求结果的复用。
用 Map 缓存 Promise 实例
最常用的方式是用一个 Map(或普通对象)以请求参数为 key,存储对应的 Promise 实例。这样相同参数的多次调用会命中缓存,拿到同一个 Promise,自然复用结果。
- Key 要能唯一标识一次请求,比如将 URL + 参数序列化成字符串
- 务必缓存 Promise 实例本身,而不是 resolve 后的值——否则无法链式调用 .then()/.catch()
- 不需要手动区分 pending/fulfilled/rejected 状态,Promise 天然支持多次 then,状态变更后所有监听者都会触发
基础缓存函数示例
以下是一个通用的 fetch 请求缓存封装:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
const cache = new Map();
function cachedFetch(url, options = {}) {
const key = JSON.stringify({ url, options });
if (!cache.has(key)) {
const promise = fetch(url, options)
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => {
cache.delete(key); // 失败可选择清除缓存,避免重复失败
throw err;
});
cache.set(key, promise);
}
return cache.get(key);
}
调用 cachedFetch('/api/user/1') 多次,只会发一次请求,后续返回同一个 Promise。
支持动态参数与过期策略
真实场景中常需更灵活的控制,比如按时间过期、按参数结构生成 key、或允许强制刷新:
- key 构建可改用 URLSearchParams 或自定义哈希函数,避免 JSON.stringify 对 undefined/null 处理不一致
- 加入 TTL:缓存时记录时间戳,get 时检查是否超时,超时则删除并重新发起
- 提供 bypassCache 选项:如
cachedFetch(url, { bypassCache: true })直接跳过缓存
注意边界情况
缓存 Promise 虽简单高效,但需留意几个易错点:
- 不要在 Promise 内部做副作用操作(如修改全局状态),因为缓存后这些操作只执行一次
- 如果请求依赖当前时间、token 等易变状态,需确保 key 包含这些变量,否则可能返回过期数据
- 错误 Promise 也会被缓存——除非主动清除,否则后续调用会立即 reject,这点和成功结果对称但容易被忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










