我正在从ES6(函数发生器)学习这个功能,我很难理解以下代码:
function* HelloGen2() {
var a = yield 100;
var b = yield a + 100;
console.log(b);
}
var gen2 = HelloGen2();
console.log(gen2.next()); // {value: 100, done: false}
console.log(gen2.next(500)); // {value: 600, done: false}
console.log(gen2.next(1000)); // {value: undefined, done: true}
问题:
1:在第一个gen2.next()
调用代码行var a = yield 100;
时,是否在var a
变量上设置了一些值?
2:在每个gen2.next()中只有直到分号执行的行?
例如,在第二次调用gen2.next(500)
中,行console.log(b);
未执行
3:我不明白最后一行gen2.next(1000)
,b变量如何得到1000值?
答案 0 :(得分:3)
yield x
和generator.next(y)
之间的关系如下:
generator.next(y)
返回 {value: x, done: false}
yield x
评估为 y
此外,生成器函数在最初调用时不会开始执行。您可以将其视为构造函数。只有在调用generator.next()
之后,实际的函数代码才会执行,直到第一个yield
语句(或函数终止)。
在你的例子中:
var gen2 = HelloGen2()
创建了生成器,但没有任何乐趣。gen2.next()
执行最多yield 100
的功能,然后返回{value: 100...}
。gen2.next(500)
恢复功能执行,首先将yield
语句评估为500(并立即将此值设置为a
),然后继续执行yield a+100
然后返回{value: 600...}
。gen2.next(1000)
恢复函数执行,首先将yield
语句评估为1000(并立即将此值设置为b
),然后继续执行直到终止,然后返回{{1} }。最后{value: undefined, done: true}
是函数而不是显式返回任何值的结果。
答案 1 :(得分:3)
使用协同程序时,理解这一点非常重要,虽然yield
和next
是不同的关键字,但它们的作用基本相同。想象一下两个协同程序通过双向通信管道连接。两个
Y = yield X
和
Y = next(X)
执行相同的操作集:
最初,主程序处于活动状态,生成器(示例中为gen2
)正在等待侦听管道。现在,当您调用next
时,主程序将一个虚拟值(null
)写入管道,从而唤醒生成器。生成器执行yield 100
,将100
写入管道并等待。主要唤醒,从管道中读取100
,记录并写入500
。生成器唤醒,将500
读入a
等等。这是完整的流程:
gen wait
main next() null -> pipe
main wait
gen pipe -> null
gen yield 100 100 -> pipe
gen wait
main pipe -> arg (100)
console.log(arg) 100
main next(500) 500 -> pipe
main wait
gen a= pipe -> a (500)
gen yield a + 100 600 -> pipe
gen wait
main pipe -> arg (600)
console.log(arg) 600
main next(1000) pipe -> 1000
main wait
gen b= pipe -> b
console.log(b) 1000
gen (ended) done -> pipe
main pipe -> arg (done)
console.log(arg)
main (ended)
基本上,为了理解生成器,你必须记住,当你指定或以某种方式使用yield/next
的结果时,在右边和左边之间会有一个暂停(或者"生成&# 34;和"使用")部分。当你这样做
var a = 5
这是立即执行的,而
var a = yield 5
涉及=
和yield
之间的暂停。这需要一些心理体操,与async
工作流程非常相似,但是随着时间的推移,你会习惯这一点。
答案 2 :(得分:2)
问题:
- 在第一个
醇>gen2.next()
调用代码行var a = yield 100;
时,是否在var a
变量上设置了一些值?
目前尚未启动,gen2.next(500)
的下次调用会获得500
的值。在第一次调用时,该值仍为undefined
。
- 在每个gen2.next()中只有直到分号执行的行?
醇>
例如,在第二次调用gen2.next(500)
中,行console.log(b);
未执行。
右。该函数在最后一个yield
语句后直接停止。
- 我不明白最后一行
醇>gen2.next(1000)
,b
变量如何获得1000值?
通过next()
的调用,该函数在最后一站继续使用yield
语句,该值将被移交并分配给b
。
执行console.log(b)
并且函数在结束时退出,生成器的结果设置为{ value: undefined, done: true }
。
function* HelloGen2() {
var a, b;
console.log(a, b); // undefined undefined
a = yield 100;
console.log(a, b); // 500 undefined
b = yield a + 100;
console.log(b); // 1000
}
var gen2 = HelloGen2();
console.log('#1');
console.log(gen2.next()); // { value: 100, done: false }
console.log('#2');
console.log(gen2.next(500)); // { value: 600, done: false }
console.log('#3');
console.log(gen2.next(1000)); // { value: undefined, done: true }
console.log('#4');

.as-console-wrapper { max-height: 100% !important; top: 0; }