ES6 introduces a new concept called Generator (or Generator function). It gives you a new way to work with iterators and functions. The ES6 generator is a new type of function that can be paused in the middle or many times in the middle and resumed later. In the standard function, control remains with the called function until it returns, but the generator function in ES6 allows the caller function to control the execution of a called function.
The difference between a generator and a regular function is:
- In response to a generator call, its code doesn’t run. In its place, it returns a special object called a ‘Generator Object’ to manage the execution.
- At any time, the generator function can return (or yield) the control back to the caller.
- The generator can return (or yield) multiple values according to the requirement, unlike a regular function.
Syntax: Generator functions have a similar syntax to regular functions. As the only difference, the generator function is denoted by an asterisk (*) after the function keyword.
function *myfunction() { }
Yield operator: In the yield statement, function execution is suspended and a value is returned to the caller. In this case, enough state is retained for the function to resume where it left off. Following the last yield run, the function resumes execution immediately after it has been resumed. You can produce a series of values using this function.
JavaScript next method: The next() method will resume the execution of the generator function when it receives an argument, replacing the yielded expression where the execution was paused with the argument from the next() method. Objects returned by the next() method always have two properties.
- value-The yielded value is the value.
- done- The completed state of a function can be expressed as a Boolean value true. Otherwise, it yields false.
Example: In this example, we take a generator function and generate 3 numbers and call the generator function 4 times in a row to see the actual output and in conclusion, we see that when we call the generator function for the fourth time it gives the value as undefined and done property as true. Because at this call the generator function already completes the generation of three consecutive numbers so when we call the function for the fourth time it gives no value and updates the done status to true it means there is no value to be generated at the fourth time.
Javascript
function * generator() { yield 1; yield 2; yield 3; } let obj = generator(); console.log(obj.next()); console.log(obj.next()); console.log(obj.next()); console.log(obj.next()); |
Output:
{ done: false, value: 1 } { done: false, value: 2 } { done: false, value: 3 } { done: true, value: undefined }
Return statement in a generator function: A return statement sends a specified value back to its caller. It ends the execution of the function call and returns the result to the caller. The statements defined after the return statement are not executed in a function. Therefore, the return statement should come at the end of the function.
Example 2: Here we used the return statement at the 3rd line to see how return works in the generator function. Normally when we write any statement after the return statement it gives an error but here when writing any yield statement after the return statement it doesn’t give any error other than it shows that the generator function call is ended it means there are no further steps to generate the number.
JavaScript
function* generator() { yield 1; yield 2; return 3; yield 4; } let obj = generator(); console.log(obj.next()); console.log(obj.next()); console.log(obj.next()); console.log(obj.next()); |
Output:
{ done: false, value: 1 } { done: false, value: 2 } { done: true, value: 3 } { done: true, value: undefined }
Calling a generator function inside another to generate a function: we can call a generator function inside another generator function by using the yield * operator (or statement).
Example 3: In this example, we call a generator function inside another generator function using the yield * statement. There are two generator functions one is named as generator and another is named as myfunction both the functions are parameter functions. Here we create an object of generator function by calling and passing the parameter to that function and inside generator function we are going to call the myfunction which is a generator function by using the yield * operator.
JavaScript
function* myfunction(k) { yield k + 1; yield k + 2; yield k + 3; } function* generator(i) { yield i; yield* myfunction(i); yield i + 5; } let obj = generator(6); console.log(obj.next()); console.log(obj.next()); console.log(obj.next()); console.log(obj.next()); console.log(obj.next()); console.log(obj.next()); |
Output:
{ done: false, value: 6 } { done: false, value: 7 } { done: false, value: 8 } { done: false, value: 9 } { done: false, value: 11 } { done: true, value: undefined }