Generators
Normally, functions follow a run-to-completion model. When a function is invoked, it runs until it completes and then returns.
However, generators are functions that can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.
Creating generator functions
function* generatorFunc() {
console.log("First");
yield "yield 1";
console.log("Second");
yield "yield 2";
console.log("Third");
return;
}Invoking a generator function returns a generator object, that has many properties that we probably won`t have to use.
yield keyword
The execution of the generator gets "paused" when it encounters a yield keyword. And the catch is that the next time we run the function, it remembered where it previously paused, and runs from there on
Invoking a generator function
The generator object contains a next method that can be used to iterate the generator object.
However in order to remember the state of the generator, we need to store the generator object in a variable.
const genObj = generatorFunc();
genObj.next();
genObj.next();
genObj.next();First
{value: "yield 1", done: false}
Second
{value: "yield 2", done: false}
Third
{value: undefined, done: true}The value of the done property is true when the return keyword is encountered.
The done property is crucial because we can only iterate a generator object once., after which it will return undefined forever.
If you want to iterate it again you have to create a new generator object.
Iterators
What make an
The generator object is an iterator, meaning we can use for of loops and the spread operator on it.
const genObj = generatorFunc();
[...genObj];
// [ "yield 1", "yield 2" ]