Functions: The Next Generator-tion








Generators
What are they?
Generator functions are functions that
can be executed in stages, and which
will maintain any internal state across
individual calls, exit control back to
consuming code wherever they're
told to exit, and start their execution
right back at the same spot when
they're called for their next step.
Huh?
Generator functions can stop and start
any number of times, depending on
how they're written, and they
remember where they left off.
Why would I need that?
Generators can assist in such things as:
- State management
- Infinite series generation
State Management
Text
const stateGenerator = function * () {
let state = {};
for (;;) {
state = Object.assign(
{},
state,
yield state
);
}
};
const state = stateGenerator();
state.next().value; // {}
state.next().value; // {}
state.next({ foo: true }).value; // { foo: true }
state.next().value; // { foo: true }
state.next().value; // { foo: true }
state.next({ bar: false }).value; // { foo: true, bar: false }
state.next().value; // { foo: true, bar: false }
state.next().value; // { foo: true, bar: false }
// etcInfinite Series Generation
const fibonacciGenerator = function * () {
let firstNum = 0;
let secondNum = 1;
yield 1;
while (true) {
const nextNum = firstNum + secondNum;
firstNum = secondNum;
secondNum = nextNum;
yield nextNum;
}
};
const fibonacci = fibonacciGenerator();
fibonacci.next().value; // 1
fibonacci.next().value; // 1
fibonacci.next().value; // 2
fibonacci.next().value; // 3
fibonacci.next().value; // 5
fibonacci.next().value; // 8
// etc
Async Generators
What are they?
const asyncRandomNumbers = async function * () {
const url =
'https://www.random.org/decimal-fractions/?num=1&dec=10&col=1&format=plain&rnd=new';
while (true) {
const response = await fetch(`${url}&cb=${Math.random()}`);
const text = await response.text();
yield Number(text);
}
};
const example = async () => {
for await (const randomNumber of asyncRandomNumbers()) {
console.log(randomNumber);
if (randomNumber > 0.95) break;
}
};
Iterables
Iterables
Iterables are a defined interface that
include the return of 2 properties in a
yielded response: done, and value.
The done property tells the consumer
when a generator function has finished
and returned, while the value property
tells the consumer what the current
value of the generator function is.
Iterables
If manually nudging a generator function
along from step to step, consumers will
need to inspect the done property if
that aspect is important. A generator
can only run from start to finish once
per invocation. If you need to perform
the work over again, you'll need to
invoke the generator all over
again and step through it.
Iterables
Iteration constructs (for, while, do/while,
etc), will automatically interpret the done
value, in order to know when to exit the
loop. This holds true for async interables.
Symbol.iterator
This is a special symbol that allows you to
define a custom iterator on an object. This
will allow you to use general iteration
constructors (for, while, do/while,
etc.) to iterate over your object
in a more simplistic way.
Symbol.iterator
const Collection = class {
constructor () {
this._records = [];
}
add (value) {
this._records.push(value);
}
get () {
return this._records;
}
[Symbol.iterator]() {
const records = this._records;
let index = 0;
return {
next: () => ({ value: records[index++], done: index > records.length }),
};
};
};
Generator Support

Async Generator Support

Resources
fn.
Functions: The Next Generator-tion
By Richard Lindsey
Functions: The Next Generator-tion
- 174