前端批量请求的并发控制与工程化实践

在上一篇文章中,我们已经完成了数据准备工作。本篇将重点介绍一个在真实业务中几乎绕不开的问题

当需要对一组数据逐个请求接口时,如何优雅、安全地进行批量请求?

如果处理不当,轻则页面卡顿,重则接口被限流甚至封禁。


一、为什么不能直接 Promise.all

最常见的写法是这样:

ini 复制代码
Promise.all(
  list.map(item => request(item))
);

这个写法的问题在于:

  • 并发数量 不可控

  • 列表一长就会:

    • 打满浏览器并发
    • 压垮后端服务
  • 一旦某个请求失败,整体直接 reject

在区县、设备、用户、文件等数量不确定的场景下,这种方式风险极高。


二、我们真正需要的是什么?

一个成熟的「批量请求」方案,至少应该满足:

  1. 限制并发数量
  2. 支持批次间隔(节流)
  3. 单个失败不影响整体流程
  4. 能够感知整体完成状态
  5. 结果和错误可以分开统计

三、核心设计思路

1️⃣ 把"请求"和"执行"解耦

  • 批量工具只负责 调度
  • 具体请求由调用方传入
javascript 复制代码
(task) => Promise

2️⃣ 固定并发数,分批执行

  • 每一批最多 N 个任务
  • 当前批次完成后,延迟一段时间再执行下一批

3️⃣ 所有任务最终返回一个统一结果

ini 复制代码
{
  results: [],
  errors: []
}

四、批量请求使用方式(示例)

下面是一个典型的使用方式:

javascript 复制代码
this.batchRequestWithLimit(
  taskList,
  (task) => {
    return apiRequest(task);
  },
  (task, data) => {
    console.log(`任务 ${task} 成功`, data);
  },
  5,   // 最大并发数
  200, // 批次间隔(ms)
)
  .then(({ results, errors }) => {
    console.log(
      `批量请求完成:成功 ${results.length} 个,失败 ${errors.length} 个`
    );
  })
  .catch(err => {
    console.error("批量请求异常:", err);
  });

从使用者视角看,这个方法具备:

  • 调用简单
  • 参数语义清晰
  • 结果可控

五、执行流程拆解(非常关键)

整个批量请求的生命周期可以拆成 5 步:

Step 1:任务队列初始化

ini 复制代码
const queue = [...taskList];

Step 2:取出当前批次

ini 复制代码
const batch = queue.splice(0, limit);

Step 3:并发执行当前批次

ini 复制代码
await Promise.allSettled(
  batch.map(task => executor(task))
);

Step 4:等待节流时间

scss 复制代码
await sleep(interval);

Step 5:继续下一批,直到队列清空


六、为什么 Promise.allSettled 是关键

相比 Promise.all

方法 任一失败 结果可控
Promise.all ❌ 整体失败
Promise.allSettled ✅ 单独失败

批量请求场景中

失败是常态,而不是异常

我们要做的是:

  • 接受失败
  • 记录失败
  • 不中断流程

七、这种模式适合哪些场景?

这种批量请求模型,适用于:

  • 区县 / 城市 / 设备 / 用户 批量拉取
  • 文件批量上传 / 下载
  • 批量校验、扫描、统计
  • 任何「数量不确定 + 接口有压力」的业务场景

八、总结一句话

批量请求不是"多发请求",而是"有节制地并发执行任务"。

通过:

  • 限制并发
  • 分批执行
  • 错误隔离
  • 统一收敛结果

你可以把一个"危险操作",变成一个可控、可扩展、可维护的工程能力

相关推荐
熊猫_豆豆2 小时前
一个模拟四轴飞行器在随机气流扰动下悬停飞行的交互式3D仿真网页,包含飞行器建模与PID控制算法
javascript·3d·html·四轴无人机模拟飞行
来恩10033 小时前
jQuery选择器
前端·javascript·jquery
前端繁华如梦3 小时前
树上挂苹果还是挂玻璃球?Three.js 程序化果实的完整实现指南
前端·javascript
CDwenhuohuo4 小时前
优惠券组件直接用 uview plus
前端·javascript·vue.js
川冰ICE4 小时前
TypeScript装饰器与元编程实战
前端·javascript·typescript
AI砖家5 小时前
Vue3组件传参大全,各种传参方式的对比
前端·javascript·vue.js
希望永不加班5 小时前
var局部变量类型推断的利弊
java·服务器·前端·javascript·html
threelab5 小时前
Three.js 3D 地图可视化 | 三维可视化 / AI 提示词
前端·javascript·人工智能·3d·着色器
失眠的咕噜6 小时前
PDA 安卓设备上传多张图片
android·前端·javascript
掰头战士6 小时前
深入了解JS原型及原型继承链机制
javascript