<p>生成器惰性遍历超大数组通过yield按需返回元素,避免内存溢出;定义function* lazyIterate(arr) { for (let i = 0; i < arr.length; i++) yield arr[i]; },调用next()时才计算下一项。</p>

用生成器惰性遍历超大数组,核心是避免一次性加载全部数据到内存,而是按需 yield 每一项。Generator 函数返回迭代器对象,调用 next() 时才计算下一个值,天然支持懒执行。
定义生成器函数遍历数组
把传统 for 循环封装进 function*,用 yield 逐个输出元素:
function* lazyIterate(arr) {
for (let i = 0; i < arr.length; i++) {
yield arr[i];
}
}
<p>// 使用示例(哪怕 arr 有百万项,也只在需要时取)
const bigArray = new Array(1000000).fill(0).map((_, i) => i);
const it = lazyIterate(bigArray);</p><p>console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 2配合 for...of 实现自动惰性消费
for...of 内部调用迭代器的 next(),适合处理“取前 N 项”或“遇到条件就停”的场景:
- 只遍历前 100 项,不会触发后续 999900 次计算
- 遇到满足条件的值可直接
break,后续元素完全不生成
function* lazyIterate(arr) {
for (const item of arr) {
yield item;
}
}
<p>const it = lazyIterate(bigArray);
let count = 0;
for (const num of it) {
if (num > 99) break; // 到 100 就停,后面全不执行
console.log(num);
count++;
}处理无法预知长度的流式数据(如文件行、API 分页)
生成器不依赖 length,适合边读边产。例如模拟逐行读大文件:
function* readLines(lines) {
for (let i = 0; i < lines.length; i++) {
// 模拟异步延迟(实际可用 await + yield* 处理 Promise)
yield lines[i];
}
}
<p>// 或者更贴近真实场景:分页拉取
async function* fetchPages(url, limit = 100) {
let offset = 0;
while (true) {
const res = await fetch(<code>${url}?limit=${limit}&offset=${offset}</code>);
const data = await res.json();
if (data.length === 0) break;
for (const item of data) yield item;
offset += limit;
}
}注意点与优化建议
- 生成器本身不解决内存泄漏——确保外部引用及时释放(如不用再保留
it) - 避免在
yield前做重操作(如深克隆整个子数组),否则仍会提前消耗资源 - 需要随机访问或多次遍历时,生成器不适合(它是一次性、单向的),应搭配缓存策略或改用其他结构
- 想支持
return()提前终止?可在生成器内监听try...finally或检查next()的done状态


















