JavaScript数组分片异步执行分四类:一、串行分批,严格顺序执行;二、并发分批(最常用),批内并行、批间串行;三、健壮版支持中断、错误跳过与结果统计;四、动态流式处理,适用于超大数组或流数据。

JavaScript 数组按批次分片并异步执行,核心是把大数组切分成小块,每块依次(或并发)用 await 等待执行完成,避免阻塞主线程、防止 Promise 暴增、也便于控制节奏(如限流、防抖、UI 更新)。
一、串行分批:每批执行完再执行下一批
适合需要严格顺序、依赖前一批结果、或资源敏感(如频繁调 API 需限速)的场景。
做法:用 for...of 或普通 for 循环,配合 await 等待每批 Promise 全部 settled。
async function processInBatches(arr, batchSize = 5, handler) {
for (let i = 0; i handler(item)));
// 可选:批次间加延迟,降低压力
// await new Promise(r => setTimeout(r, 100));
}
}
<p>// 示例:模拟异步请求
const urls = ['url1', 'url2', 'url3', 'url4', 'url5', 'url6'];
await processInBatches(urls, 2, async url => {
console.log('Fetching:', url);
await fetch(url).catch(() => {}); // 忽略错误
});
</p>二、并发分批:每批内并行,批次间串行
比纯串行快,又比全量并发更可控。每批内部用 Promise.all 并发,批次之间仍 await 隔离。
这是最常用、平衡性最好的方式。
- 批次大小建议根据任务类型调整:IO 密集型(如 fetch)可设 5–20;CPU 密集型(如复杂计算)建议 1–5
- 注意
Promise.all会因任一失败而 reject,如需“尽力执行”,改用Promise.allSettled - 可在批次处理前后插入日志、loading 状态更新等副作用
三、支持中断与错误处理的健壮版本
真实项目中常需支持取消、错误跳过、统计成功/失败数等。
示例增强点:
- 使用
Promise.allSettled避免单个失败导致整批中断 - 添加
abortSignal支持外部中止(需 handler 内部配合) - 返回结构化结果,含 success/fail 列表和耗时
async function processWithResult(arr, batchSize = 5, handler) {
const results = { success: [], fail: [] };
const start = Date.now();
<p>for (let i = 0; i handler(item).catch(err => ({ item, err, idx })))
);</p><pre class="brush:php;toolbar:false;">batchResults.forEach((r, idx) => {
if (r.status === 'fulfilled') {
results.success.push({ item: batch[idx], value: r.value });
} else {
results.fail.push({ item: batch[idx], reason: r.reason });
}
});}
results.duration = Date.now() - start; return results; }
四、进阶:动态批大小 + 连续流式处理(类似 pipeline)
当数组极大(如十万条)、内存敏感,或想边获取边处理(如读取文件流、WebSocket 消息流),可用生成器 + 异步迭代器实现“持续喂入、分片消费”:
- 用
function* batchGenerator(arr, size)创建分片迭代器 - 用
for await (const batch of batchGenerator(...))持续拉取批次 - 适合搭配
ReadableStream、AsyncIterator或自定义数据源
这种模式不一次性加载全部数组,内存友好,但实现稍重,一般中等规模用前三类足够。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











