使用信号量、批处理或任务队列控制并发请求,避免资源耗尽。1. 信号量通过acquire/release限制同时运行的任务数;2. 批处理将请求分组,逐批执行;3. 任务队列动态调度,保持最多max个并发任务。根据场景选择:信号量适合精细控制,批处理适用于简单批量操作,任务队列更优用于复杂持续任务流,平衡性能与稳定性。

在处理大量异步请求时,如果不加控制地发起所有请求,可能会导致系统资源耗尽、网络拥塞或目标服务限流。为了解决这个问题,需要对并发的请求数量进行限制。通过合理的并发控制方案,可以在保证效率的同时避免系统过载。
使用信号量(Semaphore)控制并发
信号量是一种经典的并发控制机制,用于限制同时访问某一资源的线程或任务数量。
在 JavaScript 中,可以通过类来模拟信号量行为:
class Semaphore { constructor(max) { this.max = max; this.current = 0; this.queue = []; } async acquire() { return new Promise((resolve) => { if (this.current 0) { const next = this.queue.shift(); this.current++; next(); } }}
利用该信号量,可以控制异步请求的并发执行数量:
const semaphore = new Semaphore(3); // 最多同时3个请求async function fetchWithLimit(url) { await semaphore.acquire(); try { const response = await fetch(url); return response.json(); } finally { semaphore.release(); }}
批量调度:按批次执行请求
将所有请求分成多个批次,每批只执行有限数量的请求,等部分完成后再发起下一批。
实现方式如下:
async function limitedParallelRequests(urls, maxConcurrent) { const results = []; for (let i = 0; i fetch(url).then(res => res.json())) ); results.push(...batchResults); } return results;}
这种方式简单直接,适用于不需要持续流水线处理的场景。
使用任务队列实现动态调度
更灵活的方式是维护一个任务队列,由一个调度器负责按最大并发数启动和补充任务。
示例实现:
async function runWithConcurrencyLimit(tasks, max) { const results = []; const executing = []; for (const task of tasks) { const p = Promise.resolve().then(task); results.push(p); const e = p.then(() => executing.splice(executing.indexOf(e), 1)); executing.push(e); if (executing.length >= max) { await Promise.race(executing); } } return Promise.all(results);}
这种模式能更高效地利用空闲资源,一旦有位置就立即补上新任务,提升整体吞吐量。
基本上就这些。选择哪种方式取决于具体需求:信号量适合精细控制,批处理适合简单场景,任务队列则更适合复杂或长期运行的任务流。关键在于平衡性能与稳定性。不复杂但容易忽略。
以上就是并发控制实现方案_限制异步请求的并发数量的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1540359.html
微信扫一扫
支付宝扫一扫