生成器函数是 javascript 中创建迭代器最简洁的方式,使用 function* 定义并配合 yield 关键字,自动返回符合迭代协议的迭代器对象,支持 for...of、扩展运算符等,状态自动保持且可中断恢复。

生成器函数是 JavaScript 中创建迭代器最简洁的方式,它让开发者无需手动实现 next()、done、value 等细节,只需用 function* 定义函数并配合 yield 关键字即可自动返回符合迭代协议的对象。
生成器函数天然返回迭代器对象
调用一个生成器函数(如 function* myGen() { ... })不会立即执行函数体,而是返回一个迭代器对象。该对象具备 next() 方法,每次调用都会暂停/恢复执行,并返回 { value, done } 形式的结果。
-
不用手动写
[Symbol.iterator]():生成器函数返回的迭代器默认支持for...of、扩展运算符([...gen()])、解构等原生迭代语法 -
状态自动保持:函数内部的局部变量、执行位置在多次
next()调用间被保留,无需额外闭包或类封装 -
可中断与恢复:遇到
yield暂停,下次next()继续执行后续语句,适合处理异步流程或大数据流
基础写法:用 yield 产出值
每个 yield 表达式对应一次 next() 调用的返回值。函数结束时自动返回 done: true。
function* countUpTo(n) {
for (let i = 1; i const it = countUpTo(3);
it.next(); // { value: 1, done: false }
it.next(); // { value: 2, done: false }
it.next(); // { value: 3, done: false }
it.next(); // { value: undefined, done: true }
直接用于 for...of 更自然:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
for (const num of countUpTo(3)) {
console.log(num); // 1, 2, 3
}
进阶技巧:委托其他迭代器与传参控制
用 yield* 可以“委托”另一个可迭代对象(如数组、其他生成器),把它的迭代过程嵌入当前流程;而 next(value) 的参数能向生成器内部传递数据,实现双向通信。
-
yield*复用逻辑:比如合并多个生成器或遍历嵌套结构 -
next(arg)传参:上一次yield表达式会接收到该参数,可用于动态调整行为(例如暂停后继续时跳过某些项) -
处理
return和throw:生成器可被return(value)提前终止,或用throw(err)注入异常,适合构建健壮的数据管道
实际场景示例:惰性过滤与分页迭代
生成器特别适合封装耗资源的操作,比如逐条处理大数组、模拟分页请求、或实现无限序列。
function* filterAsync(iterable, predicate) {
for (const item of iterable) {
if (predicate(item)) {
yield item;
}
}
}
<p>// 惰性过滤,不一次性构造新数组
const numbers = [1, 2, 3, 4, 5];
const odds = filterAsync(numbers, x => x % 2 === 1);</p><p>for (const n of odds) {
console.log(n); // 1, 3, 5 —— 按需计算,内存友好
}
</p>
再比如模拟分页加载:
function* fetchPage(url, pageSize = 10) {
let offset = 0;
while (true) {
const data = /* 实际 fetch 或 mock 数据 */;
if (data.length === 0) break;
yield data;
offset += pageSize;
}
}
调用方可以按需取一页,不提前拉取全部数据。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










