开始学习生成器,我遇到以下脚本。
我对第一个next()
感到困惑,为什么第一个next()没有打印console.log。
function* callee() {
console.log('callee: ' + (yield));
}
function* caller() {
while (true) {
yield* callee();
}
}
> let callerObj = caller();
> callerObj.next() // start
{ value: undefined, done: false }
// why console.log is not returning 'callee' ??
> callerObj.next('a')
callee: a
{ value: undefined, done: false }
> callerObj.next('b')
callee: b
{ value: undefined, done: false }
答案 0 :(得分:4)
当你有一个生成器时,在一个暂停阶段启动,第一个next
调用将生成器运行到第一个屈服点。当你从"屈服于"每次都是一个子发电机。如果您将记录添加到两个函数的入口点,您将看到:
function* callee() {
console.log('Callee is running up to the first yield point');
console.log('callee: ' + (yield));
}
function* caller() {
console.log('Caller is running up to the first yield point');
while (true) {
yield* callee();
}
}
使用测试代码运行此实现时,您将看到:
> let t = caller()
> t.next()
Caller is running up to the first yield point
Callee is running up to the first yield point
Object {value: undefined, done: false}
答案 1 :(得分:3)
启动生成器(callerObj.next()
)时,它始终会升至第一个yield
。
由于您将(yield *
)委托给另一个生成器,因此该生成率将是callee
中的那个:
function* callee() {
console.log('callee: ' + (yield));
// this yield ^^^^^
}
这里发生器在执行console.log
之前停止。如果您返回yield
一个值,这将是您首次value
电话的返回callerObj.next()
:
function* callee() {
console.log('callee: ' + (yield 'value'));
}
然后,下一个callerObj.next('a')
电话会将yield
的值替换为'a'
,然后拨打console.log
。在伪代码中:
console.log('callee: ' + 'a');
// `yield` is replaced with 'a' for this invocation
然后它将一直运行,直到它再次遇到相同的yield
(因为你处于无限循环中)。