什么是生成器函数在javascript中_怎样使用yield控制执行流程【教程】

10次阅读

生成器函数用 function* 声明,调用返回 Generator 对象而非立即执行;yield 交出控制权并可接收 next() 传入的值,next() 返回 {value, done} 对象,for…of 遍历忽略 return 值。

什么是生成器函数在javascript中_怎样使用yield控制执行流程【教程】

生成器函数不是普通函数,它不会立即执行,而是返回一个可迭代的 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 或函数结束
  • 返回对象固定有两个属性:valueyield 后的值或 return 的值)和 done(是否已结束)
  • 多次调用 next() 超出 yield 数量时,valueundefineddonetrue

yield 表达式能接收外部传入的值

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 自动遍历生成器,但会忽略 return 值

for...of 隐式调用 next(),直到 done: true,但它只消费 yield 出的 value,不处理 return 的值:

立即学习Java免费学习笔记(深入)”;

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 时,才值得引入。否则,普通函数加数组更直白。

text=ZqhQzanResources