Promise本身不自带缓存能力,但可通过封装实现:用闭包变量或Map缓存已解析的Promise,支持无参/参数化缓存;推荐仅缓存成功结果,失败时不写入以支持重试;可结合memoize或SWR等工具简化实现。

Promise 本身不自带缓存能力,但可以通过封装逻辑,在首次请求后把结果保存下来,后续调用直接返回已解析的 Promise,避免重复发起异步操作。
用闭包保存缓存结果
最常用的方式是用一个变量存储已 resolve 的 Promise,后续调用直接返回它:
function createCachedAsyncFn(fn) {
let cache = null;
return async function(...args) {
if (cache) return cache;
cache = fn(...args);
return cache;
};
}
// 使用示例
const fetchUser = createCachedAsyncFn(() =>
fetch('/api/user').then(r => r.json())
);
// 第一次调用发起请求,第二次直接返回缓存的 Promise
fetchUser().then(data => console.log(data));
fetchUser().then(data => console.log(data)); // 不再发请求
支持参数化的缓存(如不同 ID)
如果函数接收参数(比如用户 ID),需按参数做键值缓存,常用 Map 或普通对象:
- 用 Map 存储:key 是参数序列化后的字符串,value 是 Promise
- 注意参数顺序和类型一致性,建议用 JSON.stringify([a, b]) 作 key
- 可选加 TTL 或手动清理机制,防止内存泄漏
function createParamCachedFn(fn) {
const cache = new Map();
return async function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const promise = fn(...args);
cache.set(key, promise);
return promise;
};
}
处理失败情况(缓存 reject)
默认情况下,Promise reject 后也会被缓存,导致后续调用一直失败。如需重试,可在 catch 后清空缓存:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 捕获错误后清除对应 key 的缓存
- 或改用“只缓存成功结果”,失败时不写入缓存
- 推荐方式:成功才缓存,失败不缓存,让下次调用重试
function createSuccessOnlyCachedFn(fn) {
const cache = new Map();
return async function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
try {
const result = await fn(...args);
cache.set(key, Promise.resolve(result));
return result;
} catch (err) {
// 不缓存错误,下次调用重新尝试
throw err;
}
};
}
配合 async/await 和现代工具更简洁
实际项目中,可结合工具库简化实现:
- Lodash 的 memoize 可缓存函数结果,配合 Promise 使用需注意返回的是 Promise 实例
- SWR、React Query 等数据获取库内置了基于 key 的请求去重与缓存
- TypeScript 中可加泛型约束,保证缓存返回类型一致
核心思路不变:拦截调用 → 检查缓存 → 命中则返回已有 Promise → 未命中则执行并缓存结果。

















