JS Async/Await Fetch缓存优化:解决重复请求问题
原生JS极简解决方案
核心思路是让缓存不仅存储已获取到的数据,还能存储正在进行的请求Promise——当同一个data-key的请求还在处理时,后续请求直接复用这个Promise,等它完成后共享结果,避免重复发起请求。
以下是实现代码:
// 初始化缓存,既存最终数据也存待完成的请求Promise const asyncCache = new Map(); async function fetchByDataKey(dataKey) { // 情况1:缓存已有现成数据,直接返回 const cacheItem = asyncCache.get(dataKey); if (cacheItem && !(cacheItem instanceof Promise)) { return cacheItem; } // 情况2:已有同key的请求在处理,直接返回这个Promise等待结果 if (cacheItem) { return cacheItem; } // 情况3:无缓存也无正在进行的请求,发起新请求 const fetchPromise = fetch(`/api/data?key=${dataKey}`) .then(response => { if (!response.ok) throw new Error('请求失败'); return response.json(); }) .then(data => { // 请求成功后,把缓存里的Promise替换成实际数据 asyncCache.set(dataKey, data); return data; }) .catch(error => { // 请求失败后移除缓存中的Promise,避免后续请求一直拿到失败状态 asyncCache.delete(dataKey); throw error; // 抛出错误让调用方自行处理 }); // 将正在进行的Promise存入缓存 asyncCache.set(dataKey, fetchPromise); return fetchPromise; }
关键细节说明
- 用
Map做缓存容器比普通对象更灵活,支持任意类型的data-key(如果你的key不是字符串也能兼容) - 请求成功后替换缓存值为实际数据,后续请求直接读取结果,无需再走异步逻辑
- 请求失败时删除缓存中的Promise,保证下次请求能重新发起,不会被失败状态卡住
- 所有调用
fetchByDataKey的地方,统一通过await或.then()处理结果,无需区分是首次请求还是等待复用的请求
内容的提问来源于stack exchange,提问作者Brian Pinto
相关产品推荐
相关产品推荐

