
本文介绍如何将异步 http 请求按固定大小(如 10 个)分组并发执行,并确保整批全部完成后再处理下一批,避免服务器过载和请求超时。
本文介绍如何将异步 http 请求按固定大小(如 10 个)分组并发执行,并确保整批全部完成后再处理下一批,避免服务器过载和请求超时。
在高并发调用受限后端服务(例如仅支持 10 线程并发处理)的场景中,盲目发起大量 fetch 请求极易引发连接堆积、响应延迟甚至批量超时。虽然“动态资源复用”(如基于信号量的限流)更高效,但某些业务逻辑明确要求严格按批次提交、全批响应返回后才推进下一阶段——例如日志批量上报需保证顺序性、或下游系统依赖整批数据原子性落库。
为此,我们可封装一个通用的 executeInBatches 工具函数,其核心逻辑如下:
- 将待处理数据切分为若干子数组(每批最多
batchSize项); - 对每批数据调用工厂函数(如
makeRequest)生成 Promise 数组; - 使用
await Promise.all(promises)阻塞式等待该批所有请求完成; - 合并结果并进入下一轮循环。
以下是完整实现:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
async function executeInBatches(data, factory, batchSize = 10) {
const queue = [...data]; // 浅拷贝避免污染原数组
const results = [];
while (queue.length > 0) {
const batch = queue.splice(0, Math.min(batchSize, queue.length));
const promises = batch.map(item => factory(item));
const batchResults = await Promise.all(promises);
results.push(...batchResults);
}
return results;
}
// 示例:封装 fetch 请求
function makeRequest(url) {
return fetch(url)
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
return res.text();
})
.catch(err => Promise.reject(`Failed to fetch ${url}: ${err.message}`));
}
// 使用示例
const urls = [
'https://httpbin.org/delay/1',
'https://httpbin.org/delay/1',
'https://httpbin.org/delay/1',
// ... 更多 URL(总数可为任意值)
];
executeInBatches(urls, makeRequest, 10)
.then(allResults => {
console.log('✅ 所有批次请求已完成,共获取', allResults.length, '条响应');
})
.catch(err => {
console.error('❌ 批处理过程中发生错误:', err);
});关键注意事项:
立即学习“Java免费学习笔记(深入)”;
- ✅
Promise.all()会拒绝(reject)整个批次,只要其中任一请求失败。若需容错(即单个失败不影响其余成功响应),应改用Promise.allSettled()并自行解析fulfilled/rejected状态; - ✅
splice(0, n)原地修改queue,配合while循环确保无遗漏; - ⚠️ 避免在
factory中直接await异步操作(如未return的 async 函数),否则会导致map返回undefined而非 Promise; - ? 若需控制批次间间隔(如防抖、节流),可在
await Promise.all(...)后添加await new Promise(r => setTimeout(r, delayMs))。
此方案兼顾清晰性与可控性,是处理“强批次语义”网络调用的可靠实践。

















