生成器函数调用后返回一个 Generator 对象,它既是迭代器(含 next() 方法)又是可迭代对象(支持 for...of 和展开运算符),内部维护执行上下文,仅在调用 next() 时推进并暂停于 yield。

JavaScript 生成器(function*)不是“异步函数的简化写法”,它本身不处理异步,也不自动等待 Promise;它的核心价值是**手动控制函数执行暂停与恢复**,从而实现可中断、可迭代、状态保持的逻辑流。
生成器函数调用后返回什么?
调用 function* 不会立即执行函数体,而是返回一个 Generator 对象——它既是迭代器(有 next() 方法),也是可迭代对象(能用 for...of 或展开运算符)。
这个对象内部维护着函数的执行上下文(包括变量、执行位置),但只有在调用 next() 时才推进到下一个 yield 表达式,并暂停。
常见误解:以为 gen() 就开始跑了——其实只是“准备好跑”,真正启动靠第一次 next()。
立即学习“Java免费学习笔记(深入)”;
yield 和 return 在生成器里行为不同
yield 暂停执行并返回值,后续调用 next() 可继续;return 则终结生成器,之后所有 next() 都返回 { done: true, value: ... }。
-
yield后的表达式只在对应next()调用时求值(惰性计算) -
return值会成为最后一次next()的value,且done变为true - 生成器内部抛出未捕获错误,会直接使生成器进入
done: true状态
function* count() {
yield 1;
yield 2;
return 'done';
}
const g = count();
g.next(); // { value: 1, done: false }
g.next(); // { value: 2, done: false }
g.next(); // { value: 'done', done: true }
g.next(); // { value: undefined, done: true }(不再变化)生成器适合哪些真实场景?
它不常用于写业务主流程,但在需要“分步产出”或“状态机建模”的地方很自然:
- 无限序列生成:比如斐波那契、素数筛,避免预分配大数组
-
树/图的深度优先遍历:用
yield*委托子生成器,代码扁平无回调嵌套 -
协程式状态管理:如表单多步骤校验,每步
yield一个校验函数,上层决定何时推进 -
与
async混用(需手动驱动):co库或自写 runner 可把yield Promise转成 await 风格,但现代已基本被async/await替代
注意:for...of 自动忽略 return 值,只消费 yield 出的值;若需获取 return 值,必须显式调用 next() 直到 done: true。
容易被忽略的关键细节
生成器一旦进入 done: true 状态,就不可重用;重新调用 gen() 才能得到新实例。
yield* 委托时,被委托生成器的 return 值会成为当前 yield* 表达式的返回值,而不是丢弃。
生成器函数不能作为构造函数使用:new gen() 会抛出 TypeError。
调试时,Chrome DevTools 支持在生成器暂停处查看闭包变量,但堆栈帧显示为 “generator pause”,不是常规函数调用栈——这点让初学者误以为“卡住了”。










