1

I have this code:

function* showValue() {
  setTimeout(function*() {
    console.log('yielding')
    return yield 100;
  }, 1000);
}

var valFunc = showValue();
console.log(valFunc.next());

When I run it, I see this output:

{ value: undefined, done: true }

Why should I do to have the .next() call return 100?

Geo
  • 93,257
  • 117
  • 344
  • 520
  • `setTimeout` is asynchronous, it completes at a later time, and as such you can't just return from it. In your case you'd probably need a callback or a promise to know when the timer has done it's thing. – adeneo Aug 06 '16 at 17:41
  • True, and there's probably something I don't yet comprehend about genrators, but I was thinking that if `showValue` gets paused, yielding from somewhere, even inside a setTimeout, would resume execution. – Geo Aug 06 '16 at 17:44
  • setTimeout won't return anything other than it's id number yet the anonymous generator function provided as a callback to setTimeout will run when it's time comes and the generator object that it returns will be get lost. You have to capture it within the setTimeout and then use accordingly. – Redu Aug 06 '16 at 17:45
  • That's not how generators work. – Bergi Aug 06 '16 at 19:35
  • You might want to have a look at [Understanding asynchronous code flow with yield/generators](http://stackoverflow.com/q/23551418/1048572). Maybe you should start with learning `async`/`await`. – Bergi Aug 06 '16 at 19:39
  • 2
    Essentially a duplicate of [ES6 generators: transforming callbacks to iterators](https://stackoverflow.com/questions/29699109/es6-generators-transforming-callbacks-to-iterators) – Dan Dascalescu Jun 14 '19 at 20:52

1 Answers1

2

You might think about changing the code as follows;

function showValue() {
    return setTimeout(function() {
        function* gen() {
            console.log('yielding');
            yield 100;
        };
        var it = gen();
        console.log(it.next().value);
    }, 1000);
}
showValue();              // will display result after 1000+ms
console.log(showValue()); // will immediately display setTimeout id and after 1000+ms will display the generator yielded value again.
pinkwaffles
  • 463
  • 4
  • 12
Redu
  • 25,060
  • 6
  • 56
  • 76
  • how could this be modified so that the value is viewable when running `console.log(showValue())` ? – Geo Aug 06 '16 at 18:01
  • 1
    It can not be. setTimeout is an asynchronous function. When you call showValue it will invoke setTimeout and that will take time to do something (it won't return anything other than it's id as well) At the moment you call console.log(setTimeout()) the generator function is still waiting to be put into the event queue and will be invoked at least 1000ms later. So anything that you want it to perform must be chained to the asynchronous timeline. I will modify the code with hopes you can perceive the facts. – Redu Aug 06 '16 at 18:09