JavaScript生成器函数用function*声明,通过yield暂停执行并返回值,调用后返回迭代器,每次next()才执行一段,实现惰性求值,适合无限序列与大数据流处理。

JavaScript 的生成器函数是一种可以暂停和恢复执行的特殊函数,它天然支持惰性求值——即“需要时才计算”,而不是一次性生成全部结果。
生成器函数的基本定义与语法
生成器函数用 function* 声明,内部使用 yield 暂停执行并返回一个值。调用后不立即运行,而是返回一个迭代器对象(Iterator)。
- 每次调用迭代器的 .next() 方法,函数从上次暂停处继续执行,直到下一个 yield 或结束
- yield 表达式本身会暂停,并把右侧值作为 value 返回;函数状态(如变量、执行位置)被保留
- 函数末尾或遇到 return 时,迭代器标记为 done: true
示例:
function* count() {yield 1;
yield 2;
yield 3;
}
const it = count();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
惰性求值的核心机制
惰性求值的关键在于:生成器函数体内的代码,只在每次 .next() 被调用时才执行一段,而非启动时全量运行。这避免了提前计算、内存占用和无用运算。
立即学习“Java免费学习笔记(深入)”;
- 适合处理无限序列(如自然数、斐波那契)、大数据流或高开销计算
- 每一步都按需触发,上一步的结果可直接用于下一步逻辑,无需缓存整个数组
- 与普通数组方法(如 map、filter)不同,生成器不产生中间数组,节省内存
用生成器实现常见惰性操作
你可以组合多个生成器,像 Unix 管道一样链式处理数据流,且全程保持惰性。
- 惰性过滤:写一个 *filter(gen, pred) 生成器,只在需要时检查并跳过不满足条件的项
- 惰性映射:写一个 *map(gen, fn),对每个产出值即时变换,不预计算全部结果
- 无限序列:比如 function* naturals() { let i = 1; while(true) yield i++; } —— 它不会卡死,只在你调用 .next() 时才生成下一个数
注意点与实际限制
生成器不是万能的“懒加载魔法”,它的惰性依赖于使用者是否主动迭代。如果用扩展运算符 [...gen] 或 Array.from(gen),仍会一次性展开全部值。
- 无法随机访问(没有 gen[5]),只能顺序遍历
- 迭代器是一次性的:遍历完或中途抛错后,再次调用 .next() 会始终返回 { value: undefined, done: true }
- 异步场景中,可用 async function* 配合 yield await 实现惰性异步流(如分页请求)











