为什么此JavaScript生成器函数中的fruit变量未被赋值为'apples'?
Generator next传参时机错误导致输出不符合预期
Generator 函数中 next() 方法的传参规则是:调用 next 时传入的参数,会作为上一次执行完成的 yield 表达式的返回值,你的问题就出在参数传递的时机错了。
我们逐行拆解代码的执行流程:
- 第一次执行
g.next()- Generator 启动,执行到第一个
yield 'starting'就暂停,返回结果的value为starting,第一次调用next时传的参数会被直接忽略(因为没有上一个已完成的yield表达式),所以第一个console.log输出starting,符合预期。
- Generator 启动,执行到第一个
- 第二次执行
g.next('apples')- 你传入的
apples会作为上一个已完成的yield 'starting'表达式的返回值,但你的代码里没有用变量接收这个返回值,所以这个参数实际被浪费了。 - 代码继续向下执行,给变量
a赋值为0,直到碰到第二个yield bar()就暂停,执行bar()得到结果lol作为本次返回的value,所以第二个console.log输出lol,符合预期。 - 注意:此时
yield bar()这个表达式还没有执行完成,它的返回值要等到下一次调用next()时,由传入的参数来赋值。
- 你传入的
- 第三次执行
g.next()- 你这次没有传参,默认传入的是
undefined,这个值会作为上一个已完成的yield bar()表达式的返回值,赋值给变量fruit,所以你内部的console.log(fruit)打印的是undefined。 - 代码继续执行到
yield${a} ${fruit}``,计算得到0 undefined作为本次返回的value,所以第三个console.log输出0 undefined,和你看到的实际输出一致。
- 你这次没有传参,默认传入的是
修复方法
如果要得到你预期的输出,只需要把 apples 放到第三次调用 next 的时候传入即可,修改调用部分代码:
let g = foo1() console.log(g.next().value) console.log(g.next().value) // 第二次调用不需要传参,第一个yield的返回值没有被使用 console.log(g.next('apples').value) // 第三次传参,赋值给yield bar()的返回值也就是fruit变量
修改后的输出就和你预期的完全一致了。
内容的提问来源于stack exchange,提问作者jason
相关产品推荐
相关产品推荐

