【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;
});
相关推荐
Asthenia041225 分钟前
技术复盘:从一次UAT环境CORS故障看配置冗余的危害与最佳实践
前端
csj5030 分钟前
前端基础之《React(1)—webpack简介》
前端·react
被巨款砸中33 分钟前
前端 20 个零依赖浏览器原生 API 实战清单
前端·javascript·vue.js·web
文韬_武略1 小时前
web vue之状态管理Pinia
前端·javascript·vue.js
董世昌411 小时前
js怎样改变元素的内容、属性、样式?
开发语言·javascript·ecmascript
mosen8681 小时前
【Vue】Vue Router4x关于router-view,transtion,keepalive嵌套写法报错
前端·javascript·vue.js
鸠摩智首席音效师2 小时前
如何清除 Yarn 缓存 ?
javascript
写不来代码的草莓熊2 小时前
vue前端面试题——记录一次面试当中遇到的题(5)
前端
weixin_ab2 小时前
【HTML分离术】
前端·html
文心快码BaiduComate2 小时前
新手该如何选择AI编程工具?文心快码Comate全方位体验
前端·后端·程序员