JavaScript数组迭代器惰性求值,需调用next()按需获取{value,done};for...of支持break/return提前终止;可封装peekable工具实现预览、跳过等操作;生成器函数能插入异步逻辑实现流式控制。

JavaScript 中数组迭代器(如 Array.prototype.values()、entries()、keys())返回的是惰性求值的迭代器对象,本身不立即执行遍历,而是按需生成下一个元素——每次调用 next() 方法才计算并返回一个 { value, done } 对象。
手动调用 next() 获取单个元素
这是最直接的“按需”方式:你完全控制何时取下一个值。
- 调用
iterator.next()返回一个对象,value是当前元素(或undefined当已耗尽),done是布尔值表示是否结束 - 可多次调用,每次只推进一步,适合条件判断、提前退出、分步处理等场景
例如:
const arr = ['a', 'b', 'c'];
const iter = arr.values();
<p>console.log(iter.next()); // { value: 'a', done: false }
console.log(iter.next()); // { value: 'b', done: false }
console.log(iter.next()); // { value: 'c', done: false }
console.log(iter.next()); // { value: undefined, done: true }用 for...of 配合 break 或 return 提前终止
for...of 内部自动调用迭代器的 next(),但它支持在任意时刻中断循环,从而避免遍历全部元素。
立即学习“Java免费学习笔记(深入)”;
- 遇到满足条件的元素后用
break退出,后续元素不会被访问 - 在函数中可用
return直接跳出,更灵活 - 比
forEach更适合“按需获取首个匹配项”这类需求
例如(查找第一个大于 2 的数):
function findFirstGT2(arr) {
for (const item of arr[Symbol.iterator]()) {
if (item > 2) return item;
}
}
findFirstGT2([1, 2, 3, 4]); // 返回 3,只迭代了前 3 次封装成可暂停/恢复的工具函数
如果需要更精细的控制(比如跳过若干项、重置、查看下一个但不消耗),可以包装迭代器:
- 缓存上一次
next()结果,提供peek()查看下一个而不移动指针 - 用闭包保存迭代器状态,暴露
next()、skip(n)、take(n)等方法 - 注意:原生迭代器不可重置,需重新创建新迭代器实现“重播”
简单 peekable 示例:
function peekable(iter) {
let nextVal = iter.next();
return {
next: () => {
const val = nextVal;
nextVal = iter.next();
return val;
},
peek: () => nextVal
};
}
<p>const p = peekable(['x', 'y', 'z'].values());
console.log(p.peek()); // { value: 'x', done: false }
console.log(p.next()); // { value: 'x', done: false }
console.log(p.peek()); // { value: 'y', done: false }配合生成器函数实现自定义按需逻辑
利用 yield* 委托数组迭代器,并在其间插入条件、延迟、过滤等行为:
- 生成器函数天然支持暂停/恢复,
yield处即“按需点” - 可在
yield*前后添加任意 JS 逻辑,比如等待、日志、校验 - 适合构建流式数据处理管道(如分页拉取、节流消费)
例如(每取一个元素暂停 100ms):
async function* pacedIterator(arr, delay = 100) {
for (const item of arr) {
await new Promise(r => setTimeout(r, delay));
yield item;
}
}
<p>// 使用时可逐个 await
(async () => {
for await (const x of pacedIterator([1,2,3])) {
console.log(x); // 每隔 100ms 输出一个
}
})();


















