0

I am having a hard time reconciling these two:

const gen = function *() {
  yield 3;
  yield 4;
  return 5;
};

const rator = gen();

console.log(rator.next());  //  { value: 3, done: false }
console.log(rator.next());  //  { value: 4, done: false }
console.log(rator.next());  //  { value: 5, done: true }

The above we see all 3 values, if we call next() a fourth time, we get:

{ value: undefined, done: true }

which makes sense. But now if we use it in a loop:

for(let v of gen()){
  console.log('next:', v); // next: 3, next: 4
}

I guess I am confused why using the for-loop doesn't print next: 5, but calling next() on the iterator manually can get the return value. Can anyone explain why this is?

In other words, I would expect the for loop to print next: 5 but it doesn't.

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • The for loop is over as soon as `done` is true. The return value isn't part of the iterated sequence. It's frequently undefined. – Mark Apr 12 '19 at 03:50
  • 1
    right so the loop discards the value that accompanies the first done:true object. seems weird. –  Apr 12 '19 at 03:53

2 Answers2

0

For consistency, this seems to work?

const gen = function *() {
  yield 3;
  yield 4;
  return yield 5;
};

the return keyword doesn't seem to do anything now, though.

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 1
    This just yields 5 and then returns undefined on the next iteration. `done` is still false when it yields 5. You might as well just remove the `return` -- it's the same. – Mark Apr 12 '19 at 04:11
-1

The returned value is contained in exception.value, where exception is the StopIteration that is thrown by the generator instance when the generator frame returns.

Example:

def generator_function():
    yield 0
    yield 1
    return "text"

value_list = []
exception_list = []
try:
    a = generator_function()
    while True:
        value_list.append(next(a))
except StopIteration as e:
    exception_list.append(e)

print(value_list)
print(exception_list)
print(type(exception_list[0]), exception_list[0])
print(type(exception_list[0].value), exception_list[0].value)

Also see Generator with return statement

Mathieu CAROFF
  • 1,230
  • 13
  • 19