生成器函数是能暂停执行的函数,它返回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 更直白;一旦涉及跨调用的状态保持或外部驱动的执行节奏,生成器才不可替代。