544 words
3 minutes
并发请求控制实现原理与实践

1. 基础版本:不考虑响应的并发限制请求#

NOTE

并发限制请求是一个常见的性能优化需求,通过控制同时执行的请求数量来避免服务器过载和提高应用性能。

实现并发控制的核心在于两个关键点:

  1. 限制并发数的阈值 limit
  2. 存储等待执行请求的队列 timerQueue
TIP

实现思路:

  1. 使用队列存储超出限制的请求
  2. 维护当前执行中的请求数量
  3. 请求完成后自动从队列中取出新的请求执行

这个状态机的起点必然是从第一个请求开始的, 所以必然会执行, 当然后续再limit范围内的请求也会执行

当请求结束后,会判断timerQueue是否为空, 不为空的话, 就取出第一个请求执行

function createLimitRequest(limit: number) { let timerQueue: Array<() => Promise<void>> = [] let count = 0; function wookLoop() { if (count >= limit) { return; } if (timerQueue.length > 0) { const task = timerQueue.shift(); if (task) { count++; task(); } } } return function limitControl(fetch: () => Promise<void>) { const task = async () => { await fetch(); count--; wookLoop(); } timerQueue.push(task); wookLoop(); } }
WARNING

核心实现要点:

  • 使用闭包保存队列和计数器状态
  • 通过 async/await 处理异步请求
  • 请求完成后自动触发下一个任务

2. 进阶版本:处理响应的并发限制请求#

NOTE

在实际应用中,我们不仅需要控制请求的并发数,还需要正确处理每个请求的响应结果。这需要我们在基础版本上增加响应处理机制。

这个版本的实现借鉴了 Promise 的特性:

  • 通过 Promise 的 resolve 机制来传递响应结果
  • 保持并发控制的同时确保响应数据的正确返回
TIP

通过返回一个新的 Promise,我们可以:

  1. 控制请求的执行时机
  2. 获取请求的返回结果
  3. 维持并发控制的逻辑

wookLoop的实现保持不变, 主要是limitControl的实现返回个promise

function limitControl(fetch: () => Promise<void>) { return new Promise(resolve){ const task = async () => { const result = await fetch(); resolve(result); count--; wookLoop(); } timerQueue.push(task); wookLoop(); } }

效果预览

并发请求控制实现原理与实践
https://0bipinnata0.my/posts/react/handwritten/concurrent-request-limit/
Author
0bipinnata0
Published at
2025-03-04 09:41:54