Generator function

A generator is a normal function, but instead of returning a single value, it returns multiple values one by one. Calling a generator function doesn't execute its body immediately, but rather returns a new instance of the generator object (that is, an object that implements both, iterable and iterator protocols).

Every generator object holds a new execution context of the generator function. When we execute the next() method of the generator object, it executes the generator function's body until the yield keyword is encountered. It returns the yielded value and pauses the function. When the next() method is called again, it resumes the execution and then returns the next yielded value. The done property is true when the generator function doesn't yield any value.

A generator function is written using the function* expression. Here is an example to demonstrate this:

function* generator_function(){ 
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
let generator = generator_function();
console.log(generator.next().value);
console.log(generator.next().value);
console.log(generator.next().value);
console.log(generator.next().value);
console.log(generator.next().value);
console.log(generator.next().done);

generator = generator_function();

let iterable = generator[Symbol.iterator]();
console.log(iterable.next().value);
console.log(iterable.next().value);
console.log(iterable.next().value);
console.log(iterable.next().value);
console.log(iterable.next().value);
console.log(iterable.next().done);

The output is as follows:

1
2
3
4
5
true
1
2
3
4
5
true

There is an expression following the yield keyword. The value of the expression is what is returned by the generator function via the iterable protocol. If we omit the expression, then undefined is returned. The value of the expression is what we call, the yielded value.

We can also pass an optional argument to the next() method. This argument becomes the value returned by the yield statement, where the generator function is currently paused. Here is an example to demonstrate this:

function* generator_function(){ 
const a = yield 12;
const b = yield a + 1;
const c = yield b + 2;
yield c + 3; // Final Line
}
const generator = generator_function();
console.log(generator.next().value);
console.log(generator.next(5).value);
console.log(generator.next(11).value);
console.log(generator.next(78).value);
console.log(generator.next().done);

The output is as follows:

12
6
13
81
true

Here's the explanation of this output:

  1. On the first generator.next() call, yield 12 is called and the value 12 is returned.
  2. On the second generator.next(5) call, the previous yield (which was stored in const a) gets the passed value (that is, 5), and then the second yield (a + 1). Then, yield 5 + 1 is called and the value 6 is returned (careful: a is not 12 here).
  3. On the third generator.next(11) call, const b becomes 11, and then because it's the sum of  11 + 2, 13 is yielded.
  4. This is followed till the last process, that is, until the line Final Line, as mentioned in the example.
  5. As yield finally returns a value and its done status, after executing yield c + 3, there is apparently no value to yield. Hence, the value returned is undefined and done is true.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.137.76