start to learning generator, i am encounter the following script.
I am confused by first next()
, why the console.log is not printed for the very first next().
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 }
start to learning generator, i am encounter the following script.
I am confused by first next()
, why the console.log is not printed for the very first next().
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 }
Share
Improve this question
asked Jul 22, 2016 at 13:47
BillBill
19.3k21 gold badges88 silver badges135 bronze badges
2
- 2 whoever leave that negative there, leave your reason! i am asking something which i am confused with. – Bill Commented Jul 22, 2016 at 13:55
- 2 This article helped me understand generators and some of their practical applications. davidwalsh.name/es6-generators – jusopi Commented Jul 22, 2016 at 14:02
2 Answers
Reset to default 5When you have a generator it starts in a suspended phase and the first next
call runs the generator up to the first yield point. When you "yield from" a sub-generator, each time. If you add logging to the entry points of both your functions you will see this:
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();
}
}
When you run this implementation using your test code you will see:
> 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}
When starting the generator (callerObj.next()
), it always goes up to the first yield
.
Since you are delegating (yield *
) to another generator, that yield would be the one in callee
:
function* callee() {
console.log('callee: ' + (yield));
// this yield ^^^^^
}
Here the generator stops before executing console.log
. If you were to yield
a value back, this would be the return value
of your first callerObj.next()
call:
function* callee() {
console.log('callee: ' + (yield 'value'));
}
The next callerObj.next('a')
call will then replace the value at yield
with 'a'
and call console.log
. In pseudo-code:
console.log('callee: ' + 'a');
// `yield` is replaced with 'a' for this invocation
It will then run until it encounters the same yield
again (since you are in an infinite loop).