浏览器请求/js请求池

关于浏览器的请求并发

浏览器本身会有请求队列,控制请求并发的数量,一般都为 6-8 个,每款浏览器相差不大。当发送大批量请求时,浏览器一次只会向服务器发送 6-8 个请求,其他 pending 状态的请求都在本地排队,并没有发送到服务端,所以浏览器的并发队列已经解决单个客户端的大并发问题了。浏览器一次性发出大批量请求时,主要影响的是本地客户端(可能硬件配置低),对服务端影响很小。
看图:绿色线条代表正在发送的请求时间,灰色线条代表正在等待的请求时间,蓝色的线条代表正在接受响应时间。
在这里插入图片描述

此处我同时发送了 12 个请求,而浏览器最初仅向服务器发送了 6 个请求(绿色箭头),而剩下的 6 个进入等待状态(灰色箭头),而当有请求完成时,浏览器又向服务器发送了新的请求,保持了多个请求的并发(红框)。

请求池

场景:当需要发送大批量请求,例如大文件切片上传时可能会发送上千次请求,会造成网络拥塞,也可能会导致浏览器直接奔溃。
解决思路:通过 promise、async/await,创建一个请求池,将当前的请求限制在固定的数量,每当其中一个请求完成后立马发送新的,保证请求池中的请求一直是满的。
实现:

// 模拟一个异步请求函数
function mockRequest(id) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(`Request ${id} completed`);
      resolve(id);
    }, Math.random() * 2000); // 随机延迟时间来模拟请求处理
  });
}

// 请求池执行函数
async function requestPool(requests, poolSize) {
  const results = []; // 存储结果
  const executing = new Set(); // 正在执行的请求集合

  for (const request of requests) {
    // 如果正在执行的请求达到了池子的大小,就等待一个请求完成
    if (executing.size >= poolSize) {
      await Promise.race(executing);
    }

     
    /**
      开始一个新请求
      这里这么写的原因是,创建一个立即执行的 Promise 然后返回 request(),这样无论 request
      是否是一个异步函数,返回的 p 都会是一个 Promise 对象, p 就会存在 .then 方法,增加代码的
      健壮性。
    */
    const p = Promise.resolve().then(() => request());
    results.push(p); // 将请求的结果添加到结果数组

    // 请求开始执行时添加到正在执行的集合
    executing.add(p);
    // 请求完成后从正在执行的集合移除
    p.then(() => executing.delete(p));
  }

  // 等待所有请求完成
  return Promise.all(results);
}

// 创建100个请求
const allRequests = Array.from({ length: 100 }, (_, index) => () => mockRequest(index));

// 使用请求池执行所有请求,池大小为5
requestPool(allRequests, 5)
  .then(() => console.log('All requests completed'))
  .catch(error => console.error('An error occurred:', error));

请求池的存在的意义:

  1. 浏览器本身可以限制正在发送的并发数量,但是如果队列中等待的请求过多浏览器也可能会崩溃,而请求池可以控制当前的请求队列中的数量,使请求不需要等待,当有一个请求结束后立即放入新请求,保证请求队列中只有正在发送的请求,减少等待中的请求。
  2. 浏览器限制并发数为 6-8 个,当除了发送大批量的请求外,我还需要同时发送其他请求,这时就可以通过请求池的并发限制,减少池中正在发送的数量,使浏览器请求队列中空出位置,保证我所需的请求可以正常发送,不会因为排队而延迟,可以更精确的控制并发数量。
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值