javascript生成器是什么_yield关键字如何工作?

JavaScript生成器是用function*声明的特殊函数,调用后返回迭代器,通过yield暂停/恢复执行并双向通信;适用于惰性计算、异步流程控制和状态机建模。

JavaScript生成器是一种特殊函数,能暂停和恢复执行,适合处理异步流程、大数据流或需要按需计算的场景。它的核心是yield关键字——它不是简单返回值,而是把函数执行“冻结”在当前点,交出控制权,等下次调用再从这里继续。

生成器函数怎么定义?

function*语法声明(星号可紧贴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如何暂停与恢复?

yield像一个双向通信断点:

  • 遇到yield时,函数暂停,把右侧表达式的值作为value返回给调用者
  • 下一次调用next()时,函数从yield后 resume,且next(arg)传入的参数会成为本次yield表达式的返回值

例子:接收外部输入

function* echo() {
  const a = yield 'say something';
  console.log('got:', a); // 第二次next传的值
  yield 'done';
}
const it = echo();
console.log(it.next());     // { value: 'say something', done: false }
console.log(it.next('hello'));// 控制台打印 got: hello,返回 { value: 'done', done: false }

生成器能做什么实际事?

它天然适配迭代协议,也常用于简化异步逻辑:

  • 惰性序列生成:比如无限斐波那契数列,只在需要时算下一个
  • 手动控制异步流程:配合Promise + next()实现类似async/await的效果(早期库如co就是这么做的)
  • 状态机建模:每个yield代表一个状态,next()触发状态迁移

注意几个关键细节

yield只能出现在生成器函数内部;不能在普通函数或箭头函数里用。生成器一旦return或抛错,后续next()都返回{ value: undefined, done: true }。另外,生成器对象本身不可调用,必须通过next()驱动。