Generators and iterators were added to JavaScript in the ES2015 specification. Generators are nice because they allow you to easily take advantage of lazy-evaluation when dealing with sequences of values. They can also be used with ES2015's for ... of loops.

One interesting thing about JavaScript's implementation of generators is that you can send the generator a value.

let foo = yield bar;

If you've ever seen a code segment within a generator which looks like this, you may have been wondering what the value of foo really is. It's the value which is sent via the next method.

let generator = myGenerator();
generator.next(someValue);

An Echo Generator

Because you can send values to the generator, you can create a generator which acts as a crude echo.

Here's an example of such an echo generator:

function* echoGenerator() {
  let send = null;

  while (true) {
    const received = yield send;
    if (received === null) return;
    send = 'ECHO ' + received;
  }
}

Now let's see what happens when we use this echo generator:

const messages = ['hello', 'these', 'are', 'some', 'messages', null];

const echo = echoGenerator();

for (const message of messages) {
  console.log(`Sending: ${message}`);

  const received = echo.next(message);
  if (received.done) {
    console.log('Done receiving');
    break;
  }

  console.log(`Received: ${received.value}`);
}

Running this results in the following output:

Sending: hello
Received: null
Sending: these
Received: ECHO these
Sending: are
Received: ECHO are
Sending: some
Received: ECHO some
Sending: messages
Received: ECHO messages
Sending: null
Done receiving

You might be wondering why the first received value is null instead of 'ECHO hello'. The answer to why it first sends null is simple. When the very first next is called, send is null. But why is the second received value 'ECHO these' and not 'ECHO hello'? This is where it gets confusing.

On the first call to next, the generator gets to the first yield, yields the value null and then stops execution. The value of the expression 'yield send' has not been resolved yet. On the second call to next, the 'yield send' expression is resolved to the value 'these'. This is why it sends 'ECHO these' instead of 'ECHO hello'.