JS实现并发控制、请求合并、数据缓存

引言

在现代前端开发中,随着应用复杂度增加,接口请求管理成为性能优化的关键点。本文将深入探讨如何通过并发控制、数据缓存和请求合并等技术手段,构建高效、稳定的大规模请求解决方案。

并发控制

1.1 问题背景

当页面同时发起大量请求时,可能导致:

  • 浏览器TCP连接数达到上限(Chrome同一域名下默认6个)
  • 服务器压力剧增
  • 低优先级请求阻塞关键请求

1.2 解决方案

使用请求队列实现控制并发

js 复制代码
class RequestQ {
  private _running;
  private max;
  private queue: ((value: unknown) => void)[];
  constructor(max: number) {
    this.max = max;
    this.queue = [];
    this._running = 0;
  }

  async add(fn: () => Promise<any>) {
    if (this._running >= this.max) {
      await new Promise((resolve) => this.queue.push(resolve));
    }
    this._running++;

    try {
      await fn();
    } finally {
      this._running--;
      if (this.queue.length > 0) {
        this.queue.shift()!();
      }
    }
  }
}

这里主要使用Promise来控制任务的并发,当当前运行的个数大于max时,会挂起一个Promise等待它的resolve,这里是实现并发控制的关键。

请求合并

js 复制代码
class RequestMerge {
  private pending;

  constructor() {
    this.pending = new Map();
  }

  async request(key: string, fn: Function) {
    if (this.pending.get(key)) {
      return this.pending.get(key);
    }
    const promise = fn().finally(() => {
      this.pending.delete(key);
    });
    this.pending.set(key, promise);
    return promise;
  }
}

使用一个Map用于储存正在请求的网络请求,当相同请求来的时候,先在Map里去找是否有相同key的值,如果有直接返回,没有在去请求。

数据缓存

js 复制代码
class CacheRequest {
  private apiCache: Map<string, any>;

  constructor() {
    this.apiCache = new Map<string, any>();
    setInterval(() => {
      this.apiCache.forEach((value, key) => {
        if (Date.now() > value.expireTime) {
          this.apiCache.delete(key);
        }
      });
    }, 60000);
  }

  async request(key: string, fn: () => Promise<any>) {
    if (this.apiCache.has(key)) {
      return this.apiCache.get(key);
    }
    const expireTime = Date.now() + 300000;

    // eslint-disable-next-line no-useless-catch
    try {
      const result = await fn();
      this.apiCache.set(key, { result, expireTime });
      return result;
    } catch (error) {
      throw error;
    }
  }
}

类似与合并请求,不同的是这里是启动一个定时器,定期的去清理过期的key

相关推荐
_阿南_6 小时前
项目中新增给AI制定的代码规范
前端·程序员
名字还没想好☜7 小时前
React 实现暗黑模式切换:localStorage 持久化、SSR 首屏闪烁与跟随系统主题
前端·javascript·react.js·ecmascript·react·next.js
console.log('npc')8 小时前
Git 冲突与 AI 协助指南
前端·人工智能·git·大模型
爱学堂IT分享9 小时前
Cesium可视化系统实战课程-Cesium教程学习
前端
糖墨夕9 小时前
理解大语言模型:Agent 的“大脑”
前端·agent
Rain的Java大神之路10 小时前
JavaWeb开发如何解决跨域问题
java·前端·后端·nginx·web安全·面试·运维开发
cpolar技术支持10 小时前
浏览器也能跑本地 AI:用 Transformers.js + WebGPU 做一个最小推理 Demo,cpolar 给同事远程体验
前端·ai·cpolar·webgpu·transformers.js
计算机魔术师11 小时前
OpenAI 发布 GPT-6 Astra:多项基准刷新纪录, cybersecurity 能力达 Critical 阈值
前端
xy345311 小时前
Axure9.0中继器遮罩实现方法
前端·ui·html·axure·原型·产品设计
风骏时光牛马11 小时前
智能任务自动化协同AI工作流
前端