生成器函数是可控暂停与恢复的执行机制,用function*定义,调用返回迭代器;yield暂停执行,next()推进并传参,return终止;无法用普通函数或闭包完全模拟,本质是语言级协程。

JavaScript 生成器函数不是“高级异步写法”,而是**可控暂停与恢复的函数执行机制**——它本身不处理异步,但为 async/await、状态机、惰性序列等提供了底层能力。
生成器函数怎么定义和调用
必须用 function* 语法定义,调用后不立即执行,而是返回一个迭代器对象:
function* count() {
yield 1;
yield 2;
return 3;
}
const it = count(); // 不执行函数体
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()调用才推进到下一个yield或return - 函数体内可有多个
yield,也可没有(只靠return终止) - 直接调用
count()不会报错,但也不会输出任何东西——这是最容易忽略的“静默失败”场景
yield 和 return 的值行为差异
yield 表达式的返回值由下一次 next(arg) 的参数决定;而 return 的值固定出现在最后一次 next() 的 value 中:
function* echo() {
const a = yield 'first';
const b = yield 'second';
return a + b;
}
const it = echo();
console.log(it.next()); // { value: 'first', done: false }
console.log(it.next(10)); // { value: 'second', done: false } → a === 10
console.log(it.next(20)); // { value: 30, done: true } → b === 20
- 首次
next()传参被忽略(无上一个yield接收) -
yield左侧赋值接收的是“下一次next()的参数”,不是当前yield的值 -
return后函数彻底结束,再调用next()仍返回{ value: undefined, done: true }
为什么不能用普通函数模拟生成器
普通函数调用即执行完毕,无法保存中间状态;生成器函数的每次 next() 都在**同一个函数上下文栈中恢复执行**,变量作用域持续存在:
技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作
立即学习“Java免费学习笔记(深入)”;
function* counter() {
let i = 0;
while (true) yield ++i;
}
const c1 = counter();
console.log(c1.next().value); // 1
console.log(c1.next().value); // 2 → i 仍是同一个变量
- 闭包能保存状态,但无法“暂停执行流”;生成器是语言级的协程支持
- 试图用
setTimeout+ 闭包模拟yield,会丢失调用栈、无法中断、无法传递控制权 - Babel 编译
function*会产出大量辅助代码,说明它不是语法糖,而是运行时行为变更
真正难的不是写 yield,而是理解「执行权移交」——谁在调用 next()、何时调用、参数从哪来。漏掉一次 next(),整个流程就卡死在 yield 处,且毫无错误提示。










