Function generator returns undefined

5

Consider the following function:

function* gerador() {
    let foo = yield "a"
    let bar = yield "b"
    let baz = yield "c"

    return '${foo} ${bar} ${baz}'
}

let gen = gerador();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());

The output will be as follows:

{ value: 'a', done: false }
{ value: 'b', done: false }
{ value: 'c', done: false }
{ value: 'undefined undefined undefined', done: true }

Note that the last console.log(gen.next()); returned undefined for the variables foo , bar and baz .

What I can not understand is that the expression yield "a" returns the object { value: 'a', done: false } but the variable foo remains undefined and to assign the value, it would have to pass value to the next method next() :

let gen = gerador();
let v1 = gen.next().value;
let v2 = gen.next(v1).value;
let v3 = gen.next(v2).value;
console.log(gen.next(v3));

This would have the expected result:

{ value: 'a b c', done: true }
    
asked by anonymous 16.07.2017 / 19:48

1 answer

2

The yield is like return in generating functions, ie when the function reads yield gives returns the expression after it (the strings that you have) and pauses the execution of the function.

When you call again .next() the same thing happens with the next yeld , returning the next variable, and so on. When yield returns the expression that follows (on the same line) it does not leave anything for let and therefore they are getting undefined value.

In the end the last .next() actually calls the return of the function, since you have called 3 times the .next() and the yield have already returned before 4 o yield function is paused after doing yield of "c", and then the last .next() will invoke the return of the last line.

Look at the example below where I put console.log(typeof foo, foo); inside the function and confirm that the variables are getting undefined .

function* gerador() {
    let foo = yield "a"
    let bar = yield "b"
    let baz = yield "c"
    
    console.log(typeof foo, foo); // repara que aqui dá undefined

    return '${foo} ${bar} ${baz}'
}

let gen = gerador();
console.log(gen.next()); // dá { value: 'a', done: false }
console.log(gen.next()); // dá { value: 'b', done: false }
console.log(gen.next()); // dá { value: 'c', done: false }
console.log(gen.next()); // chama o return e dá { value: 'undefined undefined undefined', done: true }
    
16.07.2017 / 20:17