javascript生成器通过yield按需分片处理大数据,内存友好;可实现固定大小切片、跳过、重置及条件分片等自定义逻辑,支持数组、字符串、set等多种可迭代对象。

JavaScript 中生成器通过 yield 暂停执行、按需产出值,天然适合分片处理大数据——它不预先加载全部数据,而是每次只生成一片,内存友好、响应及时。
用生成器做固定大小分片
把一个大数组按指定长度切分成多个子数组,每次调用 next() 返回一片:
- 定义生成器函数,接收源数组和每片大小(
size) - 用
for循环步进,每次yield一个切片(arr.slice(i, i + size)) - 无需缓存全部结果,遍历时才计算当前片
示例:
function* chunk(arr, size) {
for (let i = 0; i // 使用
const gen = chunk([1,2,3,4,5,6,7], 3);
console.log(gen.next().value); // [1,2,3]
console.log(gen.next().value); // [4,5,6]
console.log(gen.next().value); // [7]
处理异步数据流的分片生成器
面对接口分页、文件流或无限序列,可用异步生成器(async function*)按需拉取并分片:
- 每次
yield前 await 一次请求或读取操作 - 避免一次性加载所有页,也防止并发过多
- 配合
for await...of自然消费
示例(模拟分页 API):
async function* fetchInChunks(url, pageSize = 10) {
let page = 1;
while (true) {
const res = await fetch(`${url}?page=${page}&size=${pageSize}`);
const data = await res.json();
if (data.length === 0) break;
yield data;
page++;
}
}
<p>// 消费
for await (const chunk of fetchInChunks('/api/items')) {
console.log('处理一页:', chunk.length);
// 处理当前分片,如渲染、校验、写入
}
</p>带状态控制的可中断分片生成器
有些场景需要中途停止、重置或跳过某些片,可在生成器内部维护状态,并暴露控制方法:
- 用闭包保存索引、是否暂停等状态
- 返回对象含
next()、reset()、skip(n)等方法 - 适合实时日志解析、传感器数据缓冲等流式处理
简化示意:
function createChunker(arr, size) {
let i = 0;
return {
next() {
if (i >= arr.length) return { done: true };
const chunk = arr.slice(i, i + size);
i += size;
return { value: chunk, done: false };
},
reset() { i = 0; },
skip(n) { i = Math.min(arr.length, i + n * size); }
};
}
<p>// 使用
const chunker = createChunker([1,2,3,4,5,6,7,8], 2);
console.log(chunker.next().value); // [1,2]
chunker.skip(1);
console.log(chunker.next().value); // [5,6]
</p>与迭代器协议结合实现自定义分片逻辑
生成器本质是符合迭代器协议的对象,你可以封装更复杂的分片策略(如按条件切分、滑动窗口、动态大小):
- 在
yield前加入判断逻辑:例如遇到特定值才切片、累计和超阈值才输出 - 支持非数组输入(字符串、Set、甚至自定义可迭代对象)
- 便于组合:如
filter+chunk+map链式处理
例如按字段分组分片(类似 SQL 的 GROUP BY):
function* groupByChunk(items, keyFn) {
const groups = new Map();
for (const item of items) {
const key = keyFn(item);
if (!groups.has(key)) groups.set(key, []);
groups.get(key).push(item);
// 每积累满 5 条同组数据就 yield 一次
if (groups.get(key).length >= 5) {
yield groups.get(key);
groups.set(key, []); // 清空已产出的组
}
}
// 剩余未满的也 yield 出来
for (const chunk of groups.values()) {
if (chunk.length > 0) yield chunk;
}
}
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











