You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:05:22