JavaScript Generators - ES6

Generators functions take the following form function* name() {}. Or our preferred const name = function* () {};, since we avoid function declarations in favor of function expressions.

Calling a generator doesn't actually run any of its contents. A call to a generator returns a generator instance.

const foo = function* () {
  console.log("foo");
}

// No console output here
// bar is now an instance of the generator and the console.log has never been run.
const bar = foo();

To use a generator instance we have to call .next()

const foo = function* () {
  console.log("here");
}

// No console output here
const bar = foo();

bar.next(); //=> "here"

.next() returns an object that looks like this:

{ value: undefined, done: true }

What do value and done mean?

done means that the generator doesn't have any more code to execute. AKA we are past the last yield statement. To understand value, we have to look at yield.

const foo = function* (x) {
  yield x;
}

const bar = foo(3);

console.log(bar.next()); //=> {value: 3, done: false}

console.log(bar.next()); //=> {value: undefined, done: true}

A yield statement tells the generator to stop executing and return the following value. You can have yield statements without a return value. The generator will return done: true on the subsequent call to next after the last yield statement (see above).

JavaScript - ES6