使用 Service Worker 限制请求并发数

原理

  1. 监听 fetch 事件,在事件处理函数中判断当前并发数是否超过限制。
  2. 如果超过限制,将请求加入队列,等待其他请求完成。
  3. 如果没有超过限制,直接发送请求。

实现

在 index.html 中注册 Service Worker

html 复制代码
<!DOCTYPE html>
<html lang="zh_CN">
  <body>
    <div id="app"></div>
    <script>
      if ("serviceWorker" in navigator) {
        window.addEventListener("load", () => {
          navigator.serviceWorker.register("/sw.js", {
            scope: "/",
          });
        });
      }
    </script>
    <script type="module" src="./src/main.ts"></script>
  </body>
</html>

添加 sw.js

js 复制代码
// 最大并发数
const MAX_CONCURRENT = 8;
let activeCount = 0;
const requestQueue = [];
self.skipWaiting();
self.addEventListener("fetch", (event) => {
  // 对部分接口进行限制并发数,其他请求直接放行,例如对包含 xxx.api. 的接口限制并发数
  if (!["xxx.api."].some((item) => event.request.url.includes(item))) {
    return;
  }
  // 克隆请求对象,因为请求体只能读取一次
  const request = event.request.clone();
  // 将请求加入队列
  const promise = new Promise((resolve, reject) => {
    requestQueue.push({ request, resolve, reject });
    processQueue();
  });

  event.respondWith(promise);
});

function processQueue() {
  // 队列为空或已达到最大并发数则不处理
  if (requestQueue.length === 0 || activeCount >= MAX_CONCURRENT) {
    return;
  }

  // 从队列中取出下一个请求
  const { request, resolve, reject } = requestQueue.shift();
  activeCount++;

  // 处理请求
  fetch(request)
    .then((response) => {
      resolve(response);
    })
    .catch((error) => {
      reject(error);
    })
    .finally(() => {
      activeCount--;
      processQueue(); // 处理下一个请求
    });
}

检查 Service Worker 是否生效

接口前有特殊图标或者实际的请求接口有 from service worker 表示成功。

在 Application 中也能查看对应的 Service Worker 是否注册成功

相关推荐
黄毛火烧雪下16 小时前
React Native (RN)项目在web、Android和IOS上运行
android·前端·react native
fruge16 小时前
前端正则表达式实战合集:表单验证与字符串处理高频场景
前端·正则表达式
baozj17 小时前
🚀 手动改 500 个文件?不存在的!我用 AST 撸了个 Vue 国际化神器
前端·javascript·vue.js
用户40993225021217 小时前
为什么Vue 3的计算属性能解决模板臃肿、性能优化和双向同步三大痛点?
前端·ai编程·trae
海云前端117 小时前
Vue首屏加速秘籍 组件按需加载真能省一半时间
前端
蛋仔聊测试17 小时前
Playwright 中route 方法模拟测试数据(Mocking)详解
前端·python·测试
零号机17 小时前
使用TRAE 30分钟极速开发一款划词中英互译浏览器插件
前端·人工智能
疯狂踩坑人17 小时前
结合400行mini-react代码,图文解说React原理
前端·react.js·面试
Mintopia17 小时前
🚀 共绩算力:3分钟拥有自己的文生图AI服务-容器化部署 StableDiffusion1.5-WebUI 应用
前端·人工智能·aigc
街尾杂货店&17 小时前
CSS - transition 过渡属性及使用方法(示例代码)
前端·css