JavaScript | Generator

13 Jun, 2022
Like Python Generators, JavaScript also supports Generator functions and Generator Objects.Generator-Function : A generator-function is defined like a normal function, but whenever it needs to generate a value, it does so with the yield keyword rather than return. The yield statement suspends function’s execution and sends a value back to caller, but retains enough state to enable function to resume where it is left off. When resumed, the function continues execution immediately after the last yield run. Syntax :  
// An example of generator function
function* gen(){
     yield 1;
     yield 2;
     ...
     ...
}
Generator-Object : Generator functions return a generator object. Generator objects are used either by calling the next method on the generator object or using the generator object in a “for of” loop (as shown in the above program) The Generator object is returned by a generating function and it conforms to both the iterable protocol and the iterator protocol. 
javascript
<script>// Generate Function generates three// different numbers in three callsfunction * fun(){    yield 10;    yield 20;    yield 30;   } // Calling the Generate Functionvar gen = fun();document.write(gen.next().value);document.write("<br>");document.write(gen.next().value);document.write("<br>");document.write(gen.next().value);</script>                   
Below is an example code to print infinite series of natural numbers using a simple generator. 
javascript
<script>// Generate Function generates an// infinite series of Natural Numbersfunction * nextNatural(){    var naturalNumber = 1;     // Infinite Generation    while (true) {        yield naturalNumber++;    }} // Calling the Generate Functionvar gen = nextNatural(); // Loop to print the first// 10 Generated numberfor (var i = 0; i < 10; i++) {     // Generating Next Number    document.write(gen.next().value);     // New Line    document.write("<br>");}</script>
Output  
1
2
3
4
5
6
7
8
9
10
Below is an example of how to manually return from a generator 
javascript
<script> var array = ['a', 'b', 'c'];function* generator(arr) {  let i = 0;  while (i < arr.length) {    yield arr[i++]  }} const it = generator(array); // we can do it.return() to finish the generator </script>
Encountering yield and yield* syntaxyield: pauses the generator execution and returns the value of the expression which is being written after the yield keyword.yield*: it iterates over the operand and returns each value until done is true. 
javascript
<script> const arr = ['a', 'b', 'c']; function* generator() {  yield 1;  yield* arr;  yield 2;} for (let value of generator()) {  document.write(value);  document.write("<br>");} </script>
Output  
1
a
b
c
2
Another method to create iterable 
javascript
<script> var createOwnIterable = {  *[Symbol.iterator]() {    yield 'a';    yield 'b';    yield 'c';  }} for (let value of createOwnIterable) {  document.write(value);  document.write("<br>");} <script>
Output  
a
b
c
Return from a generator function  
javascript
<script> function* generator() {  yield 'a';  return 'result';  yield 'b';} var it = generator();document.write(JSON.stringify(it.next()));// {value: "a", done: false}document.write(JSON.stringify(it.next()));// {value: "result", done: true} </script>
How to throw an exception from generator 
javascript
<script> function* generator() {  throw new Error('Error Occurred');} const it = generator();it.next();// Uncaught Error: Error Occurred </script>
Calling a generator from another generator 
javascript
<script> function* firstGenerator() {  yield 2;  yield 3;} function* secondGenerator() {  yield 1;  yield* firstGenerator();  yield 4;}  for (let value of secondGenerator()) {  document.write(value)  document.write("<br>");} </script>
Output  
1
2
3
4
Limitation of Generators you can’t yield inside a callback in generators  
javascript
<script> function* generator() {  ['a', 'b', 'c'].forEach(value => yield value) // This will give syntax error} </script>
Using async generators (for api call) 
javascript
<script> const firstPromise = () => {  return new Promise((resolve, reject) => {    setTimeout(() => resolve(1), 5000)  })} const secondPromise = () => {  return new Promise((resolve, reject) => {    setTimeout(() => resolve(2), 3000)  })} async function* generator() {  const firstPromiseResult = await firstPromise();  yield firstPromiseResult;  const secondPromiseResult = await secondPromise();  yield secondPromiseResult;} var it = generator();for await(let value of it){  document.write(value);  document.write("<br>");} </script>
Output  
(after 5 seconds)
1 
(after 3 seconds)
2
Advantages of generators: They are memory efficient as lazy evaluation takes place, i.e, delays the evaluation of an expression until its value is needed.use-case (generators)  
writing generators in redux-saga
async-await (Implemented with promise and generators)
Supported Browser:
Google Chrome 39 and above
Microsoft Edge 13 and above
Firefox 26 and above
Opera 26 and above
Safari 10 and above
khandelwalsarthak31193
ysachin2314
Pushpender007
nikhatkhan11
javascript-functions
JavaScript-Misc
JavaScript
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.