Generator

Generator functions can be paused, returned, and resumed, comparable to the StartCoroutine() function in Unity.Calling a generator function returns an iterator.


function* idMaker() {
  var index = 0;
  while (true) yield index++;
}

var gen = idMaker();
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

0 1 2

Arguments can be passed into the iterator.


function* logGenerator() {
  console.log(yield);
  console.log(yield);
  console.log(yield);
}

var gen = logGenerator();
gen.next();
gen.next(1);
gen.next(2);
gen.next(3);

1 2 3

'return'prevents the generator from resuming.


function* gf() {
  yield 1;
  return 2;
  yield 3;
}

var gen = gf();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());

{value: 1, done: false} {value: 2, done: true} {value: undefined, done: true}

To nest generators, use yield * instead.


function* anotherGenerator(i) {
  yield i + 1;
  yield i + 2;
}

function* generator(i) {
  yield i;
  yield* anotherGenerator(i);
  yield i + 10;
}

var g = generator(10);
console.log(g.next().value);
console.log(g.next().value);
console.log(g.next().value);
console.log(g.next().value);

10 11 12 20

Generators are not constructable.


function* f() {}
var obj = new f;  // throws "TypeError: f is not a constructor"

To tell if a function is a generator function:


function isGenerator(fn) {
  return fn.constructor.name === 'GeneratorFunction';
}

function f() {}
function* g() {}

console.log(isGenerator(f));
console.log(isGenerator(g));
console.log(g instanceof (function*(){}).constructor);

false true true