用闭包实现受控并发请求计数管理,核心是封装count与max于私有作用域,提供acquire、release、getActiveCount、canAcquire等安全接口,并支持队列调度与错误清理。

用闭包实现受控的并发请求计数管理,核心是把计数器和控制逻辑封装在函数作用域内,避免全局污染,同时提供安全的增减接口和状态检查能力。
封装计数器与状态判断逻辑
闭包可以将当前并发数 count 和最大允许并发数 max 保存在私有作用域中,外部只能通过返回的函数操作,无法直接修改:
function createRequestLimiter(max = 5) {
let count = 0;
return {
// 尝试发起请求:成功则计数+1,返回true;已达上限则返回false
acquire() {
if (count < max) {
count++;
return true;
}
return false;
},
// 请求完成:计数-1(需确保调用时机正确)
release() {
if (count > 0) count--;
},
// 获取当前并发数(只读)
getActiveCount() {
return count;
},
// 是否还有余量
canAcquire() {
return count < max;
}
};
}
配合 Promise 管理真实请求生命周期
单纯增减计数不够,必须和异步请求绑定。推荐在请求开始前 acquire(),在 finally 中 release(),确保异常或成功都释放资源:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
const limiter = createRequestLimiter(3);
async function limitedFetch(url) {
if (!limiter.acquire()) {
throw new Error(`Request rejected: reached max concurrency (${limiter.getActiveCount()}/${limiter.max})`);
}
try {
const res = await fetch(url);
return await res.json();
} finally {
limiter.release();
}
}
// 使用示例
limitedFetch('/api/users/1').then(console.log);
limitedFetch('/api/users/2').then(console.log);
// 超出限制时会立即抛错,不发请求
支持排队等待的增强版本
如果不想拒绝请求,而是让超额请求排队等待,可在闭包中维护一个等待队列,用 Promise 链触发后续执行:
立即学习“Java免费学习笔记(深入)”;
function createQueuedLimiter(max = 5) {
let count = 0;
const queue = [];
function processQueue() {
if (queue.length && count < max) {
const { resolve } = queue.shift();
count++;
resolve();
}
}
return {
acquire() {
return new Promise(resolve => {
if (count < max) {
count++;
resolve();
} else {
queue.push({ resolve });
}
});
},
release() {
if (count > 0) {
count--;
processQueue();
}
},
getActiveCount() {
return count;
}
};
}
使用时 await limiter.acquire(),确保只有拿到许可才发请求,释放后自动唤醒下一个。
实际集成建议
- 每个服务模块(如用户API、订单API)应独立创建 limiter 实例,避免互相干扰
- 若用 axios,可通过拦截器统一注入 acquire/release,但注意错误路径也要 release
- 结合 AbortController 可在排队超时或取消时清理队列项
- 调试时可加日志输出
console.log('acquired', limiter.getActiveCount()),但生产环境建议关闭

















