Introduction
ES6 introduced new type of functions called Generator Functions. A function keyword with an asterisk * is used to define a generator function.
function* generatorFunction(i) {
yield i;
yield i + 10;
}
const generator = generatorFunction(1);
console.log(generator.next().value); //1
console.log(generator.next().value); //11
Demo
A Generator Function can be called as many times as desired. Every time the function is called it returns a special type of iterator object called Generator. Generators are unique, calling the function by next() method returns a new Generator. The next() method returns an object with a Value property containing the yield value and a done property which is a Boolean indicating whether the generator has yielded its last value.
//Normal functions
function normalFunction() {
console.log("cannot");
console.log("be");
console.log("stopped");
}
normalFunction()// cannot be stopped
//Generator function
function* generatorFunction() {
yield console.log("can");
yield console.log("be");
yield console.log("stopped");
}
const generator = generatorFunction();
generator.next().value; // can
generator.next().value; // be
generator.next().value; // stopped
Demo
Memory Efficient
Generator Functions are memory efficient, they can be stopped midway or suspend function execution to yield values on demand and continue from where it was stopped by calling next().
They are efficient when iterating over a large data set(or an infinite list). Most of the time we may not want to iterate through the full list and want to generate only what is needed at that time.
function* generatorFunction(max) {
let number = 0;
//iterate over an infinite count to generate squared numbers
while (number < max) {
number++;
yield number * number;
}
}
const max = Infinity;
let iterationCount = 0;
const totalIterations = 5;
const squaredNumber = generatorFunction(max);
//generate first 5 squared numbers
while (iterationCount < totalIterations) {
iterationCount++;
console.log(squaredNumber.next().value);
}
Demo
Using Return in the Generator Function
When the return statement gets executed then the done property will be set to true. Any subsequent next() method will not be executed. Note that any error that is not caught in the function execution will finish the function as well and returns.
function* generatorWithReturn(i) {
yield i; //returns i
return i; //returns i
yield i; //returns undefined
}
var gen = generatorWithReturn("conitnue")
console.log(gen.next()); // { value: "continue", done: false }
console.log(gen.next()); // { value: continue, done: true }
console.log(gen.next()); // { value: undefined, done: true }
Demo