自定义迭代器通过在 next() 方法中使用 throw 语句抛出异常,异常会同步中断迭代流程并被调用方(如 for...of、array.from() 或手动调用)捕获;常见场景包括迭代器耗尽后继续调用、非法参数校验失败或底层资源不可用。

在 JavaScript 中,自定义迭代器抛出异常的方式和其他函数一致:在 next() 方法内部使用 throw 语句即可。关键在于异常会在调用方(如 for...of、Array.from() 或手动调用 iterator.next())中被同步捕获。
在 next() 方法里直接 throw
自定义迭代器对象必须实现 next() 方法,该方法可返回 { value, done } 对象,也可选择抛出错误。只要在执行逻辑中遇到非法状态(如数据耗尽后继续取值、参数校验失败等),就可主动 throw。
- 错误会中断当前迭代流程,后续的
next()不再被调用 -
for...of遇到异常会立即退出,并将错误抛给外层 try/catch - 手动调用时,需用 try/catch 包裹
it.next()才能捕获
常见抛异常的场景
以下情况适合抛出异常,而非返回 { done: true }:
- 迭代器已耗尽,但调用方仍尝试获取下一个值(例如重复调用
next()多次) - 构造迭代器时传入非法参数(如负数步长、null 数据源),可在首次
next()中校验并 throw - 底层资源不可用(如网络请求失败、文件读取出错),且无法恢复
示例:带校验和耗尽检查的迭代器
下面是一个每次返回递增数字、最多 3 次的迭代器,超出后抛出 RangeError:
const limitedCounter = (limit = 3) => {
let count = 0;
return {
[Symbol.iterator]() { return this; },
next() {
if (count >= limit) {
throw new RangeError('Iterator is exhausted');
}
return { value: count++, done: false };
}
};
};
// 使用
const it = limitedCounter(2);
console.log(it.next()); // { value: 0, done: false }
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // 抛出 RangeError
注意异常传播行为
迭代器异常是同步的,不会被 Promise 或异步操作隐式吞掉:
-
for...of中的throw会立刻终止循环 -
Array.from(it)遇到异常会中止构建数组,并把错误抛出 - 如果
next()返回 Promise(即异步迭代器),则需用throw在 async 函数内,或 reject Promise
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











