什么是JavaScript的生成器函数?

生成器函数用function*声明,通过yield暂停执行并产出值,每次调用next()推进一步;可接收外部传入值实现双向通信,常用于自定义迭代器、大数据流处理及异步流程控制。

生成器函数是JavaScript中一种特殊的函数,能**暂停和恢复执行**,每次调用都返回一个迭代器对象,适合处理异步流程、惰性求值或分步生成数据的场景。

生成器函数怎么定义?

function*(星号紧贴function关键字)声明,函数体内可用 yield 暂停执行并产出一个值:

function* count() {
  yield 1;
  yield 2;
  yield 3;
}
const iterator = count();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

yield 和 return 的区别

yield 是暂停点,可多次出现,每次调用 next() 向前推进一步;return(或函数自然结束)表示迭代完成,done: true,后续值被忽略:

  • yield 42 → 返回 {value: 42, done: false}
  • return 'done' → 返回 {value: 'done', done: true}
  • 之后再调用 next(),始终返回 {value: undefined, done: true}

生成器函数能接收外部传入的值吗?

可以。每次调用 next(value) 时传入的参数,会作为上一个 yield 表达式的返回值:

function* echo() {
  let input = yield 'ready?';
  yield `you said: ${input}`;
}
const it = echo();
console.log(it.next());        // { value: 'ready?', done: false }
console.log(it.next('hello')); // { value: 'you said: hello', done: false }

这个特性让生成器能实现双向通信,常用于协程式控制流(比如配合Promise手动管理异步)。

实际中常用在哪儿?

  • 实现自定义迭代器:让对象支持 for...of
  • 处理大数据流:逐块读取文件或分页请求,避免内存溢出
  • 简化异步逻辑:配合 co 库或手写 runner,替代回调地狱(async/await 出现前的重要方案)
  • 状态机建模:每个 yield 对应一个状态,next() 触发状态迁移

基本上就这些。生成器不是日常必用功能,但理解它有助于掌握JS执行模型和现代异步机制的底层逻辑。