生成器函数通过yield暂停执行并保存状态,每次next()恢复至下一yield;yield右侧值为next()返回的value,next(arg)参数成为上一yield的计算结果;yield*委托遍历其他可迭代对象。

生成器函数通过 yield 暂停执行,每次调用迭代器的 next() 方法时恢复到下一个 yield 处,实现协程式的流程控制。
yield 是暂停点,不是返回值终点
yield 表达式本身会暂停函数执行,并把右侧的值(如 yield 42 中的 42)作为 next() 调用的返回结果中的 value。但函数并未结束,内部状态(如变量、执行位置)被保留。
- 第一次调用
next():执行到第一个yield并暂停,返回{ value: ..., done: false } - 后续调用
next():从上一个yield暂停处继续,执行到下一个yield或函数结尾 - 函数自然结束或遇到
return:返回{ value: ..., done: true },之后再调用next()都返回{ value: undefined, done: true }
yield 可接收外部传入的值
next(arg) 的参数会成为上一个 yield 表达式的计算结果。这是实现双向通信的关键。
function* counter() {
let count = 0;
while (true) {
const step = yield count; // 暂停,等待 next() 传值
count += step ?? 1;
}
}
<p>const it = counter();
it.next(); // { value: 0, done: false }
it.next(5); // { value: 5, done: false } → step = 5,count 变成 5
it.next(); // { value: 6, done: false } → step = undefined,count 变成 6</p>
用 yield* 委托另一个生成器
yield* 用于把当前生成器的执行权“委托”给另一个可迭代对象(通常是另一个生成器),自动遍历其所有 yield 值,简化嵌套逻辑。
- 相当于把被委托生成器的每个
yield值,逐一在当前生成器中yield出来 - 被委托生成器结束后,控制权交回原生成器,继续执行后续代码
- 支持任意可迭代对象:
yield* [1, 2, 3]、yield* generatorFn()、yield* new Set(['a','b'])
常见用途与注意事项
生成器适合需要手动控制执行节奏的场景,比如异步流程模拟、状态机、惰性序列生成等。
- 不能直接调用生成器函数获得结果,必须先调用它得到迭代器对象,再用
next() -
for...of会自动调用next(),直到done: true,但会忽略return的值 - 生成器函数不能被
async/await直接 await,需配合async function* ()(异步生成器)或手动包装 - 调试时注意:断点打在
yield行,首次进入会停;再次next()才走到下一行,容易误判执行流











