如何基于fetch与Promise实现分批并行批量API请求
基于Promise与fetch的分批并发请求实现
以下实现完全对齐你给出的RxJS版本的行为逻辑:按固定批次拆分请求,单批次内请求并行发送,当前批次全部执行完成后再发起下一批,不会占满浏览器同域名请求队列,避免阻塞其他独立发起的API请求。
注意:和RxJS的Observable懒执行特性不同,
fetch/axios等请求方法只要被调用就会立即发起请求,因此不要提前执行请求方法,需要把每个请求包装成无参函数,等轮到对应批次执行时再调用触发请求,否则分批控制会失效。
核心实现代码
/** * 分批并行请求控制函数 * @param {Array<() => Promise<any>>} requestTasks 懒执行请求任务列表 * @param {number} batchSize 单批次最大并发数,默认值为6 * @returns {Promise<Array<any>>} 按原始顺序排列的所有请求结果 */ async function bufferedRequests(requestTasks, batchSize = 6) { const finalResults = []; // 逐批次遍历处理 for (let index = 0; index < requestTasks.length; index += batchSize) { // 截取当前批次的任务 const currentBatchTasks = requestTasks.slice(index, index + batchSize); // 对齐原RxJS中forkJoin的逻辑:当前批次所有请求并行执行,任意一个请求报错则直接终止整个流程 const batchResults = await Promise.all( currentBatchTasks.map(task => task()) ); // 逐批返回结果,对应原RxJS subscribe的next回调 console.log(batchResults); finalResults.push(...batchResults); } // 所有批次执行完成,对应原RxJS subscribe的complete回调 console.log('complete'); return finalResults; }
调用示例
对应你原代码中的urls数组,写法调整为懒执行的任务列表即可:
// 所有请求包装为函数,初始化时不会发起请求 const requestTasks = [ () => fetch('url1').then(res => res.json()), () => fetch('url2').then(res => res.json()), () => fetch('url3').then(res => res.json()), // 剩余1000+个请求按相同格式追加即可 ]; // 启动分批请求 bufferedRequests(requestTasks) .then(allResults => { console.log('全部请求执行完成', allResults); }) .catch(err => { // 对应原RxJS subscribe的error回调 console.log(err); });
可选调整
- 如果需要单批次内单个请求失败不打断整体流程,可以把代码中的
Promise.all替换为Promise.allSettled,即可拿到每个请求的成功/失败状态,不会因为单个请求异常终止后续批次。 - 如果需要动态调整批次大小、支持中途暂停/继续,只要在循环内加对应状态判断即可,性能和RxJS实现无差异,在1000+请求规模下运行稳定。
内容的提问来源于stack exchange,提问作者Drenai
相关产品推荐
相关产品推荐

