What is a Generator and how do differentiate between function and Generator?
// function* means that its a generator
function normalFunction() {
}
function* generatorFunction() {
}
A Generator is a type of Iterator.
What is an Iterator?
let's understand it with a simple example.
/* input is an array [1,2,3] and the iterator is a magical
method that gives us the next value till the time
we come to an end */
iterate.next();
// {value: 1, done: false}
iterate.next();
// {value: 2, done: false}
iterate.next();
// {value: 3, done: true}
Generator functions return a generator object
function* genFunction() {
yield "Start of Generator";
}
// Generator Object
let genObj = genFunction();
genObj.next();
// Output: {value: "Start of Generator", done: false }
genObj.next();
// Output: {value: undefined, done: true }
.next() advances it to the yield if present and pauses there and return stops and done becomes true
Let's take one more example
function* salaryGenerator() {
console.log("Monthly Logger");
console.log("Working on Feature 0");
yield "Salary Recieved for January";
console.log("Monthly Logger");
console.log("Working on Feature 1");
yield "Salary Received for February";
console.log("Monthly Logger");
console.log("Working on Feature 2");
yield "Salary Received for March";
console.log("Monthly Logger");
console.log("Working on Feature 3");
return "Let's Enjoy for Time being";
}
// Generator Object
let genObj = salaryGenerator();
genObj.next();
/*
Monthly Logger
Working on Feature 0
Output: {value: "Salary Recieved for January", done: false }
*/
genObj.next();
/*
Monthly Logger
Working on Feature 1
Output: {value: "Salary Received for February", done: false }
*/
genObj.next();
/*
Monthly Logger
Working on Feature 2
Output: {value: "Salary Received for March", done: false }
*/
genObj.next();
/*
Monthly Logger
Working on Feature 3
Output: {value: "Let's Enjoy for Time being", done: true }
*/
Generators are also Iterables
function* numberGen() {
yield 1;
yield 2;
yield 3;
yield 4;
}
function main() {
for(let val of numberGen()) {
console.log(val);
}
console.log([...numberGen()]);
}
main();
/*
1
2
3
4
[1, 2, 3, 4]
*/
Custom Iterables with @@iterator Generators in Action
function tableMultiply() {
let obj = {
table: [2,3,4,5],
multiple: [5],
[Symbol.iterator]: function* () {
for(let i of this.table) {
for(let j of this.multiple) {
yield i*j;
}
}
}
};
console.log([...obj]);
}
tableMultiply();
//Output [10, 15, 20, 25]
Lazy Evaluation and Infinite Sequence
function* infinity() {
let i = 1;
while(true) {
yield i++;
}
}
function* take(n,iterable) {
for(let item of iterable) {
if(n<=0) return ;
n--;
yield item;
}
}
function* cube(iterable,cubeFunc) {
for(let item of iterable) {
yield cubeFunc(item);
}
}
console.log([...take(5,cube(infinity(),(x)=> x*x*x))]);
// Output: [1, 8, 27, 64, 125]
There is always more to Generators out there you can always read this Blog Link