Function generator returns Undefined

Asked

Viewed 64 times

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 }

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

What I can’t understand is that expression yield "a" returns the object { value: 'a', done: false } but the variable foo remains undefined and to assign the value, you would have to pass as parameter the value in 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));

So I would have expected a grudge:

{ value: 'a b c', done: true }
  • 1

    Interesting question! +1

1 answer

2

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

When you call again .next() the same thing happens to the next yeld, returning the next variable, etc. When the yield returns the expression you have next (in the same row) leaves nothing for the let and so they become valuable undefined.

In the end the last .next() actually calls the return function, because you called 3 times the .next() and the yield have already given their return, before the 4the yield function was paused after doing the yield of "c", and then this last .next() will invoke the return last-line.

Look at the example below where I put console.log(typeof foo, foo); within the function and which confirms that the variables are 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 }

  • 1

    "Yield is like a "Return didn’t know it, now it makes sense. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.