生成器函数用 function* 声明,调用返回 Generator 对象而非立即执行;yield 交出控制权并可接收 next() 传入的值,next() 返回 {value, done} 对象,for...of 遍历忽略 return 值。
生成器函数不是普通函数,它不会立即执行,而是返回一个可迭代的 Generator 对象;yield 不是暂停“当前函数”,而是交出控制权,等下一次 next() 调用时才从断点继续。

必须用 function* 声明(星号紧贴 function 关键字),调用后不运行函数体,只返回 Generator 实例:
function* count() {
yield 1;
yield 2;
return 3;
}
const gen = count(); // 此刻什么都没打印
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: true }
next() 是唯一触发执行的方式,每次调用都推进到下一个 yield 或函数结束value(yield 后的值或 return 的值)和 done(是否已结束)next() 超出 yield 数量时,value 为 undefined,done 为 true
yield 不只是“产出”,它本身是个表达式,可以被赋值——上一次 next(value) 传入的参数,会成为当前 yield 表达式的计算结果:
function* echo() {
const a = yield 'first';
console.log('a:', a); // 第二次 next(10) 传入的 10 在这里被接收
const b = yield 'second';
console.log('b:', b);
}
const it = echo();
console.log(it.next()); // { value: 'first', done: false }
console.log(it.next(10)); // a: 10 → { value: 'second', done: false }
console.log(it.next(20)); // b: 20 → { value: undefined, done: true }
next() 传参无效(没地方接收),惯例传 undefined 或不传next(x) 中的 x,会成为**上一个** yield 表达式的值Promise 手写 async/await 模拟for...of 隐式调用 next(),直到 done: true,但它只消费 yield 出的 value,不处理 return 的值:
function* nums() {
yield 1;
yield 2;
return 'done!';
}
for (const n of nums()) {
console.log(n); // 只输出 1 和 2
}
// 'done!' 被丢弃了
return 值,必须手动调用 next() 并检查 done
Array.from(nums())、[...nums()] 等展开语法也只取 yield 值,同理忽略 return
throw)或外部用 gen.throw() 注入错误,会中断执行流——这点常被忽略,调试时容易卡在静默失败真正难的不是写 yield,而是判断何时该用生成器:数据流需懒加载、状态机需精确控制暂停/恢复、或封装异步逻辑又不想用 async 时,才值得引入。否则,普通函数加数组更直白。