Power of JS Generators

Power of JS Generators

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

Did you find this article valuable?

Support ANURAG SARAN by becoming a sponsor. Any amount is appreciated!