You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript生成器执行流程疑问:为何最后再次输出before yield?

为什么JavaScript生成器最后会再次执行before yield的日志?

我写了一段JavaScript生成器测试代码:

function* listener() {
  console.log('listening');
  while (true) {
    console.log('before yield'); /** Why this is getting print in end again**/
    let msg = yield;
    console.log('after yield', msg);
  }
}

let l = listener();
l.next('are you there?');
console.log('-----');
l.next('how are you?');

运行输出为:

listening
before yield
-----
after yield how are you?
before yield

整体输出看似正常,但我不理解为何代码流程最后会再次回到console.log('before yield')并执行输出,希望有人帮忙讲解这一概念。


解答

把生成器的执行步骤拆解开,就能明白这个现象:

  1. 第一次调用l.next('are you there?'):

    • 调用listener()只是创建生成器对象,不会立即执行函数体,第一次next()才会启动执行。
    • 函数先打印listening,进入while(true)循环后打印before yield。
    • 遇到yield语句时生成器暂停执行,停在let msg = yield;这一行(还没给msg赋值)。另外,第一次next()传入的参数会被忽略——这个参数是用来传递给上一次yield的返回值,但此时还没有上一次的yield。
  2. 执行console.log('-----'):

    • 这是普通同步日志打印,和生成器执行无关。
  3. 第二次调用l.next('how are you?'):

    • 生成器从上次暂停的yield处恢复,把传入的'how are you?'赋值给msg。
    • 执行console.log('after yield', msg),打印出after yield how are you?。
    • 循环继续,回到while(true)开头,再次执行console.log('before yield'),随后又碰到yield语句,生成器再次暂停——这就是最后那条before yield的来源。

简单说,每次调用next()恢复生成器后,代码会一直执行到下一个yield才暂停。第二次next()跑完after yield的日志后,循环回到开头执行before yield,然后再次因yield暂停,所以这条日志出现在了输出末尾。


内容的提问来源于stack exchange,提问作者Vishal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 22:37:27