我有一个简单的生成器函数
function *generate(arg) {
console.log(arg)
for(let i = 0; i < 3;i++) {
console.log(yield i);
}
}
然后我启动生成器并尝试在控制台中打印值:
var gen = generate('arg'); //doesn't print
gen.next('a'); // prints 'arg'
gen.next('b'); // prints 'b'
gen.next('c'); // prints 'c'
// ... nothing surprising later
来自第一个a
来电的参数next()
去了哪里?有没有办法在发电机功能中使用它?
这是Babel REPL,您可以在其中看到该结果。
答案 0 :(得分:3)
next
方法定义如下:
25.3.1.2 Generator.prototype.next ( value )
next
方法执行以下步骤:
- 让 g 成为此值。
- 返回GeneratorResume( g ,值)。
醇>
GeneratorResume抽象操作在步骤10使用 value :
25.3.3.3 GeneratorResume ( generator, value )
带有参数生成器和的抽象运算GeneratorResume value执行以下步骤:
- 让 genContext 为 generator 的[[GeneratorContext]] internal slot的值。
醇>
- 使用suspended( value )作为操作的结果,恢复 genContext 的NormalCompletion评估 suspended它。让结果为恢复返回的值 计算。
醇>
第一种可能性是使用yield
(即"suspendedYield"
州)暂停了评估。
其行为在14.4.14 Runtime Semantics: Evaluation中解释:
YieldExpression :
yield
- 返回GeneratorYield(CreateIterResultObject(未定义, 的假强>))。
醇>
(类似于 YieldExpression :yield
AssignmentExpression )
GeneratorYield抽象操作暂停生成器,如下所示:
- 醇>
设置 genContext 的代码评估状态,以便在使用Completion resumptionValue 恢复评估时 将执行以下步骤:
- 返回 resumptionValue 。
- 注意:这将返回对最初调用此抽象操作的 YieldExpression 生产的评估。
因此,作为第二个next
的参数传递的值将用作第一个yield
表达式的返回值。并且作为第3个next
的参数传递的值将用作第2个yield
表达式的返回值。等等。
但是,生成器还有可能尚未启动(即"suspendedStart"
状态)。
这是由GeneratorStart抽象操作完成的:
- 设置 genContext 的代码评估状态,以便在为execution context以下{{3}}恢复评估时 将执行以下步骤:
醇>
但那些“后续步骤”不使用恢复值。
因此,作为第一个next
的参数传递的值将被丢弃。
答案 1 :(得分:2)
不,你不能使用第一个值。如果您将代码更改为:
,这将是有益的'use strict';
function *generate(arg) {
console.log(arg)
for(let i = 0; i < 3;i++) {
console.log(yield i);
}
return 'done';
}
var gen = generate('arg');
console.log(gen.next('a'));
console.log(gen.next('b'));
console.log(gen.next('c'));
console.log(gen.next('d'));
当您实例化生成器时,它还没有开始执行,也没有记录任何内容。在第一个gen.next('a')
上,您运行第一个产量,该产量通过生成器中的console.log(arg)
然后执行yield 0
。然后在调用者中获取console.log
,然后获得{value: 0, done:false}
等,直到完成迭代。总体输出如下:
arg
{ value: 0, done: false }
b
{ value: 1, done: false }
c
{ value: 2, done: false }
d
{ value: 'done', done: true }
最终done
是返回值,如果省略生成器上的undefined
,则为return
。