生成器函数是能暂停执行的函数,它返回Generator对象而非直接返回值,通过function*定义并用yield产出值后挂起,每次next()调用恢复执行至下一个yield。

生成器函数是能暂停执行的函数
生成器函数不是普通函数,它运行时可以中途暂停、保存当前状态,并在后续调用中从暂停处继续。关键在于它返回一个 Generator 对象,而不是直接返回值。定义方式很明确:函数名前加 *,比如 function* myGen() 或 const gen = function*() {}。
yield 是生成器内部的暂停与产出指令
yield 不是返回值后结束,而是“产出一个值,然后挂起”。每次调用生成器对象的 next() 方法,函数会执行到下一个 yield 表达式,把右边的值作为 value 返回,并暂停;下次再调用 next(),才继续执行后续代码。
function* counter() {
yield 1;
yield 2;
return 3;
}
const it = counter();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: true }
-
yield右侧表达式只在next()被调用时求值,支持惰性计算 - 首次调用
next()才开始执行函数体,yield之前的代码此时才运行 - 传给
next(value)的参数会成为上一个yield表达式的返回值(可用于双向通信) -
yield不能出现在普通函数、箭头函数或async函数中
常见误用:把生成器当普通函数调用
直接调用 counter() 不会得到 1,而是返回一个未启动的 Generator 对象。必须显式调用 next() 才触发执行。另一个典型错误是忽略 done 字段——循环遍历时若不检查 done === true,容易多走一次,拿到 { value: undefined, done: true }。
- 不要写
counter()期望得到数字;要写counter().next().value -
for...of会自动调用next()并忽略return语句产出的终值(即return 3中的3不会被遍历到) -
yield*用于委托另一个可迭代对象(如另一生成器、数组),注意它会展开整个迭代过程
实际用得上的场景其实很具体
生成器不是语法糖,它的价值集中在需要精确控制执行节奏的地方。比如实现状态机、处理异步流程(早期 co 库)、模拟协程、或构建无限序列(如斐波那契流)。
立即学习“Java免费学习笔记(深入)”;
- 用
yield实现分页请求:每次next()触发一次fetch,结果通过yield吐出 - 测试中模拟长时间运行任务:用
yield暂停,方便注入断言或 mock 行为 - 避免大数组一次性生成占用内存:生成器可按需产出下一个值,配合
take(100)类工具轻松截取
真正难的不是写对 yield,而是判断「这里是否真的需要暂停语义」——多数循环、映射、过滤,用 map/filter 更直白;一旦涉及跨调用的状态保持或外部驱动的执行节奏,生成器才不可替代。










