Friday, October 19, 2018

The Basics Of ES6 Generators - Javascript

With ES6 generators, we have a different kind of function, which may be paused in the middle, one or many times, and resumed later, allowing other code to run during these paused periods.

 The function* declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object.

Syntax :
First, the new declaration syntax:
function *addnumber() {
    // ...
}

The Basics Of ES6 Generators - Javascript

Some basic stuff to remember while working with generator function :
  • The generator functions are normally built using yield expressions.
  • Each yield inside the generator function is a stopping point before the next execution cycle starts.
  • Each execution cycle is triggered by means of next() method on the generator.
  • On each next() call, the yield expression returns its value in the form of an object containing the following parameters.
{ value: 12, done: false } // assuming that 12 is the value of yield

Value :-  is everything that is written on the right side of the yield keyword, it can be a function call, object or practically anything. For empty yields this value is undefined.
Done  :- indicates the status of the generator, whether it can be executed further or not. When done returns true, it means that the function has finished its run.

Generator Life cycle :
 Each time a yield is encountered the generator function returns an object containing the value of the encountered yield and the done status. Similarly, when a return is encountered, we get the return value and also done status as true. Whenever, done status is returned as true, is essentially means that the generator function has completed its run, and no further yield is possible.

Example -1 :
In this example,  we are assigning Yield to a Variable.
var check = function*() {
  var one = yield 1;
  var two = yield 2;
  var three = yield 3;
  console.log(one, two, three);
};

var gen = check(); //get the generator ready to run
//when you run next() on a generator, it runs until a yield, then waits until next() is called again
console.log(gen.next()); //{value:1, done: false}
console.log(gen.next()); //{value:2, done: false}
console.log(gen.next()); //{value:3, done: false}
console.log(gen.next()); //{value:undefined, done: true}
console.log(gen.next()); //errors because you can't call next() on a closed generator

Output :
> Object { value: 1, done: false }
> Object { value: 2, done: false }
> Object { value: 3, done: false }
> undefined undefined undefined
> Object { value: undefined, done: true }
> Object { value: undefined, done: true }

Example -2 :
In this example, we are passing arguments to the next() method.
var check = function*() {
  var one = yield 1;
  var two = yield 2;
  var three = yield 3;
  console.log(one, two, three);
};

var gen = check(); //get the generator ready to run
//when you run next() on a generator, it runs until a yield, then waits until next() is called again
console.log(gen.next()); //{value:1, done: false}
console.log(gen.next(1)); //{value:2, done: false}
console.log(gen.next(2)); //{value:3, done: false}
console.log(gen.next(3)); //{value:undefined, done: true}
console.log(gen.next()); //errors because you can't call next() on a closed generator

Output :
> Object { value: 1, done: false }
> Object { value: 2, done: false }
> Object { value: 3, done: false }
> 1 2 3
> Object { value: undefined, done: true }
> Object { value: undefined, done: true }

Example -3 :
In this example, we are passing arguments to the next() method and capturing the variable value in console.
var check = function*(i) {
  console.log(i)
  var one = i + (yield 1);
  console.log(one)
  var two = i + (yield 2);
  console.log(two)
  var three = yield 3;
  console.log(three)
  console.log(one, two, three);
};

var gen = check(10); //get the generator ready to run
//when you run next() on a generator, it runs until a yield, then waits until next() is called again
console.log(gen.next()); //{value:1, done: false}
console.log(gen.next(1)); //{value:2, done: false}
console.log(gen.next(2)); //{value:3, done: false}
console.log(gen.next(3)); //{value:undefined, done: true}
console.log(gen.next()); //errors because you can't call next() on a closed generator

Output :
> 10
> Object { value: 1, done: false }
> 11
> Object { value: 2, done: false }
> 12
> Object { value: 3, done: false }
> 3
> 11 12 3
> Object { value: undefined, done: true }
> Object { value: undefined, done: true }

Example - 4 :
In this example, we are using yield with return.
var check = function*(i) {  
  var one = i + (yield 1);  
  var two = i + (yield 2);  
  var three = yield 3;  
  return (one+ two+ three);
};

var gen = check(10); //get the generator ready to run
//when you run next() on a generator, it runs until a yield, then waits until next() is called again
console.log(gen.next()); //{value:1, done: false}
console.log(gen.next(1)); //{value:2, done: false}
console.log(gen.next(2)); //{value:3, done: false}
console.log(gen.next(3)); //{value:26, done: true}
console.log(gen.next()); //errors because you can't call next() on a closed generator

Output :
> Object { value: 1, done: false }
> Object { value: 2, done: false }
> Object { value: 3, done: false }
> Object { value: 26, done: true }
> Object { value: undefined, done: true }

In case of any question, please do comment in comment box below.

No comments:

Post a Comment