【26-请求缓存】js实现一个请求缓存的功能-bysking

功能总结

BcRequestCacheStore 类实现了一个基于内存的请求缓存机制,主要用于避免重复请求、减少接口调用次数以及提高性能。以下是其主要功能点: 缓存管理

  • 使用 Map 数据结构存储缓存数据 (cache) 和正在执行的请求 (bcRequestCache)。
  • 每个缓存项包含 value(缓存值)和 expiry(过期时间),支持 TTL(Time To Live)机制。

请求去重 : - 如果多个并行请求具有相同的 key,只会发送一次实际请求,其余请求会等待该请求完成并返回结果,避免重复调用接口。

缓存命中与过期检查 : - 在发起请求前,先检查缓存中是否存在对应 key 的数据。 - 如果缓存未过期,则直接返回缓存值;如果已过期,则清理缓存并重新发起请求。

错误处理: - 如果请求失败,会捕获错误并抛出异常,同时不会污染缓存。

缓存清除 : - 提供 clear 方法,用于清空所有缓存数据。

实例化 : - 通过 export const cacheRegStore = new BcRequestCacheStore(5000); 创建了一个全局缓存实例,TTL 设置为 5 秒。

使用示例

  • 调用 cacheRegStore.request 方法时,传入一个唯一标识 key 和一个异步请求函数 requestFn
  • 示例中,key 是动态生成的字符串(如 uniq_id_${id}),requestFn 是调用 apiFromServer 的异步函数。

核心逻辑

缓存优先:优先从缓存中获取数据,减少不必要的网络请求。

并发控制 :通过 bcRequestCache 管理正在执行的请求,避免重复调用。

生命周期管理:缓存有明确的过期时间,确保数据的新鲜度。

适用场景 适用于需要频繁调用相同接口且结果在一定时间内不会变化的场景,例如:

  • 数据查询接口(如用户信息、配置信息等)。
  • 需要限制请求频率的场景。
js 复制代码
class BcRequestCacheStore {
  cache; // 存放请求的函数,结果
  ttl; // 缓存过期时间
  bcRequestCache: Map<string, Promise<unknown> | null>; // 存放请求的函数,避免同时发送相同请求
  constructor(ttl = 60000) {
    this.cache = new Map();
    this.bcRequestCache = new Map();
    this.ttl = ttl;
  }

  async request(
    key: string,
    requestFn: (...args: unknown[]) => Promise<unknown>,
  ) {
    // 检查缓存值
    if (this.cache.has(key)) {
      const { value, expiry } = this.cache.get(key);

      // 缓存过期时间检查
      if (expiry > Date.now()) {
        return value;
      }

      // 缓存过期清理
      this.cache.delete(key);
    }

    // 判断是否正在执行,是的话就等待, 处理并行请求相同请求的场景,如果已经有一个相同请求真正发送,直接等待它即可,不需要重新创建
    if (this.bcRequestCache.get(key)) {
      return this.bcRequestCache.get(key);
    }

    try {
      // 发送一个新请求,并加入缓存集合
      this.bcRequestCache.set(key, requestFn());

      // 获取请求成功的值并加入缓存
      const value = await this.bcRequestCache.get(key);
      this.cache.set(key, {
        value,
        expiry: Date.now() + this.ttl,
      });

      // 请求完成后讲请求缓存集合设置空
      this.bcRequestCache.set(key, null);
      return value;
    } catch (error) {
      console.error('Request failed:', error);
      throw error;
    }
  }

  clear() {
    this.cache.clear();
  }
}

/** 接口缓存实例*/
export const cacheRegStore = new BcRequestCacheStore(5000);

const res = await cacheRegStore.request(`uniq_id_${id}`, async () => {
  let resData = await apiFromServer({
    id,
  });

  return resData;
});
相关推荐
审小匠OpenCPAi13 分钟前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution6117 分钟前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化
mONESY19 分钟前
React useState 核心原理与最佳实践:从异步更新到性能优化全解
javascript
腻害兔33 分钟前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
whyfail40 分钟前
前端学 Spring Boot(2):一次点击,如何穿过整个后端?
前端·spring boot·后端
AI多Agent协作实战派1 小时前
AI多Agent协作系统实战(二十三):Agent读HEARTBEAT.md不读AGENTS.md——openclaw的文件加载之谜
前端·数据库·人工智能·uni-app
gis开发之家1 小时前
《Vue3 从入门到大神37篇》Vue3 源码详解(七):watch 与 watchEffect 源码对比——副作用是如何被追踪的?
javascript·前端框架·vue3·vue3源码
2601_955760072 小时前
如何用 Claude Opus 5 API 批量扩展长尾关键词和文章选题
前端·python·搜索引擎
KaMeidebaby2 小时前
卡梅德生物技术快报|bli亲和力检测gst:告别批量跑胶:BLI实时酶切监测技术加速GST融合蛋白下游流程优化
前端·网络·数据库·人工智能·算法
bloglin999993 小时前
langchain 和 langgraph 和 react
javascript·react.js·langchain