JavaScript中Iterator实现无限数据流的核心是返回含next()方法的对象,其{value, done}中done恒为false;生成器函数(function*)因惰性求值和yield特性成为首选,手动实现则需闭包维护状态,工程中常封装take/takeWhile等限制逻辑。

JavaScript 中 Iterator 实现无限数据流生成,核心在于返回一个符合迭代器协议的对象:它必须有 next() 方法,每次调用返回 { value, done };而“无限”意味着 done 永远为 false,value 按需动态计算。
用生成器函数(Generator)最简洁
生成器函数天然支持惰性求值和暂停恢复,是实现无限迭代器的首选方式。只需用 function* 定义,内部用 yield 不断产出值,不写 return 就不会结束。
- 例如生成无限递增整数序列:
function* infiniteNumbers() {
let i = 0;
while (true) {
yield i++;
}
}
<p>const it = infiniteNumbers();
console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 2注意:不能直接展开([...infiniteNumbers()])或遍历到底,否则会卡死。实际使用时需配合 take、filter 等限制逻辑。
手动实现迭代器对象(非生成器)
如果不用生成器,可手写一个带闭包状态的对象,确保 next() 每次返回新值且 done: false。
立即学习“Java免费学习笔记(深入)”;
- 例如生成斐波那契无限序列:
function fibonacciIterator() {
let a = 0, b = 1;
return {
next() {
const current = a;
[a, b] = [b, a + b];
return { value: current, done: false };
}
};
}
<p>const fib = fibonacciIterator();
console.log(fib.next().value); // 0
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2关键点:状态(a, b)保存在闭包中,next() 纯函数式更新并返回,不依赖外部变量重置。
结合可中断与条件终止的实用封装
真正工程中,无限迭代器常需支持“取前 N 个”或“满足某条件时停”。可封装辅助函数,如 take 或 takeWhile:
-
take(n, iter):只消费前 n 个值 -
takeWhile(predicate, iter):直到 predicate 返回 false 停止
function take(n, iter) {
const result = [];
for (let i = 0; i < n; i++) {
const { value, done } = iter.next();
if (done) break;
result.push(value);
}
return result;
}
<p>// 使用示例:取前 5 个偶数(来自无限自然数)
function<em> naturals() {
let i = 0;
while (true) yield i++;
}
function</em> evens() {
for (const n of naturals()) {
if (n % 2 === 0) yield n;
}
}
console.log(take(5, evens())); // [0, 2, 4, 6, 8]注意事项与边界处理
无限迭代器不是“无限制滥用”的代名词。实际应用中需注意:
- 避免裸露调用
for...of,务必加数量或条件约束 - 若需重用,每次调用生成器函数都会创建新迭代器(状态独立),而手动对象只能用一次
- 异步无限流(如事件流、WebSocket 消息)可用
AsyncIterator,结构类似但next()返回 Promise - 内存友好:确保每次
next()只计算当前值,不预先生成整个序列
不复杂但容易忽略。


















