【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;
});
相关推荐
wenzhangli72 小时前
Ooder A2UI 核心架构深度解析:WEB 拦截层的设计与实现
前端·架构
前端百草阁2 小时前
【前端性能优化全链路指南】从开发编写到构建运行的多维度实践
前端·性能优化
神探小白牙2 小时前
eCharts 多系列柱状图增加背景图
javascript·ecmascript·echarts
女生也可以敲代码2 小时前
AI时代下的50道前端开发面试题:从基础到大模型应用
前端·面试
ZhengEnCi2 小时前
M5-markconv自定义CSS样式指南 📝
前端·css·python
IT_陈寒3 小时前
SpringBoot自动配置的坑差点让我加班到天亮
前端·人工智能·后端
xingpanvip3 小时前
星盘接口开发文档:星相日历接口指南
android·开发语言·前端·css·php·lua
@PHARAOH3 小时前
WHAT - GitLens supercharged 插件
前端
TT模板3 小时前
苹果cms整合西瓜播放器XGplayer插件支持跳过片头尾
前端·html5
Wect4 小时前
React 性能优化精讲
前端·react.js·性能优化