前端控制批量请求并发

最近准备做大文件上传的业务,就联想到前段时间很火的面试题🤦‍♂️ 假如有100条请求,前端如何控制并发。因此在网上看了一些优化相关性能的方案,简单记录一下

不做并发

js 复制代码
async upload(Chunks) {
let queue = [...chunks];
 while (i<queue.length) {
       //此方法是自定义的上传异步方法不赘述
	let uploadRes = await this.uploadFetch(queue[i])
        if(uploadRes){
        console.log('成功')
        }else{
        // 可写异常 再重试
        //重试优化先不写  queue.push(queue[i])
        }
        i++;
     }			
  },

局限

  • 资源利用率差,对于文件片段多的时候全部接口成功等待长时间。

promnise.all分组并发

将请求数组均分为多个小数组,每次最多只开启concurrency个并发请求,以此来控制并发数量。每当一组请求完成后再发送新的一批请求,可以实现对异步任务的并发控制。

js 复制代码
        //concurrency 参数为并发数量
      **浏览器并发限制是指浏览器对同一域名同时发起的HTTP请求数量的上限**‌,通常限制在6-8个之间 **
        //Chrome/Firefox:默认6个 假如预留一个空闲位的话concurrency设置为5 
	async concurrencyUpload(chunks,concurrency) {
	let queue = [...chunks];
	while (queue.length > 0) {
	const currentChunks = queue.splice(0, concurrency);
	 await Promise.all(
	      currentChunks.map(async chunk => {
	      try {
                //此方法是自定义的上传异步方法
		await this.uploadFetch(chunk);
		} catch (err) {
		// 重试:将分片重新加入队列
                //可优化重试逻辑 控制单任务重试次数
		// queue.push(chunk);
		}
		})
		).catch(err => console.error('出错:', err));
		}
		}

局限

  • 当前批次请求全部完成后才会继续下一批次,可能存在空闲位。
  • 可能返回无序的结果。
  • 有一个请求失败了,这个 Promise.all就失败了,没有返回值。

使用队列

另一种方式是使用一个队列来手动管理并发。你可以创建一个函数来管理并发请求的发送。

js 复制代码
class RequestQueue {
  constructor(maxConcurrent) {
    this.maxConcurrent = maxConcurrent;
    this.queue = [];
    this.running = 0;
  }

  enqueue(promiseFn) {
      this.queue.push(promiseFn);
      this.processQueue();
    });
  }

  processQueue() {
    while (this.running < this.maxConcurrent && this.queue.length > 0) {
      const  promiseFn = this.queue.shift();
      this.running++;
      promiseFn()
        .then(()=>{
        //console.log('单任务返回成功')
        })
        .catch(()=>{
        // 重试:将上传任务重新加入队列
         //可优化重试逻辑 控制单任务重试次数
        this.queue.push(promiseFn)
        })
        .finally(() => {
          this.running--;
          this.processQueue(); // Process the next item in the queue
        });
    }
  }
}

// 使用示例
const queue = new RequestQueue(5); // 最大并发5个请求

// 请求函数 uploadFetch 已经是一个promise方法
chunks.forEach(chunk=>{queue.enqueue(this.uploadFetch(chunk))})

用第三方库 p-limit

安装依赖
js 复制代码
npm install p-limit
js实现
js 复制代码
import pLimit form 'p-limit';

const limit = pLimit(2); // 限制并发数为2
const results = await Promise.all(chunks.map(chunk => limit(() => this.uploadFetch(chunk))));
相关推荐
夏幻灵1 小时前
HTML5里最常用的十大标签
前端·html·html5
Mr Xu_2 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝2 小时前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions2 小时前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发2 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
程序员猫哥_2 小时前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html
龙飞052 小时前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
我爱加班、、2 小时前
Websocket能携带token过去后端吗
前端·后端·websocket
AAA阿giao2 小时前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
杨超越luckly2 小时前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强