6

I'm tackling Generators in ES6, and I would like to understand, conceptually, what's happening in the function below:

function* createNames() {
    const people = [];

    people.push(yield);
    people.push(yield);
    people.push(yield);

    return people;
}

const iterator = createNames();
iterator.next('Brian');
iterator.next('Paul');
iterator.next('John');
iterator.next(); // output: ["Paul", "John", undefined]

My question is: why does the first push is ignored? Shouldn't the array be something like people = ['Brian', 'John', 'Paul', undefined]? Sorry for the silly question, but I would really love to be able to fully grasp this. Thanks in advance!

Bruno Mazza
  • 675
  • 1
  • 10
  • 24
  • 1
    This is by design. Iterators invert the control to the caller and thus allow iterating a collection lazily. If calling a generator function would immediately mutate the iterator's state, this semantics would be broken. –  Apr 17 '18 at 14:29

1 Answers1

4

Invoking createNames() does not execute any of the code inside of the generator. It creates an instance of an iterator, and execution begins on the first next() call.

const iterator = createNames(); 
// Iterator instance created, but hasn't executed yet.

iterator.next('Brian');
// creates the people array
// attempts to push, yields
iterator.next('Paul');
// pushes 'Paul'
// attempts to push, yields
iterator.next('John');
// pushes 'John'
// attempts to push, yeilds
iterator.next(); 
// pushes undefined
// returns ["Paul", "John", undefined]
thgaskell
  • 12,772
  • 5
  • 32
  • 38