Table of contents
1.
Introduction
2.
What is Javascript Generator Function?
3.
Syntax of Generator Function in JavaScript
4.
Methods of JS Generator Function
5.
Working of Generator Function in JS
5.1.
JS
6.
Examples of Generator Function
6.1.
Example 1 - Having yield* 
6.2.
JS
6.3.
Example 2 - Passing arguments
6.4.
JS
6.5.
Example 3 - Having Return statement 
6.6.
JS
6.7.
Example 4 - Having Throw statement
6.8.
JS
6.9.
Example 5 - Generator example
6.10.
JS
7.
How to Throw an Exception from a Generator Object?
7.1.
JS
8.
Advantages of using the Generator Function
9.
Disadvantages of Generator Function
10.
Frequently Asked Questions
10.1.
Define generator object.
10.2.
Describe yield and yield*.
10.3.
When should I use generators in JavaScript?
10.4.
What is the difference between a generator function and a normal function in JavaScript?
10.5.
Why do we need a generator function?
11.
Conclusion
Last Updated: Jan 7, 2025

Generator Function in JavaScript

Author Pankhuri Goel
0 upvote

Introduction

Generators are functions that can be exited and re-entered at a later time. Across re-entrances, their context (variable bindings) will be preserved. On-demand, generators can return ("yield") many values one after the other. They work well with iterables, making it simple to design data streams.

Generators in Javascript, especially when used with Promises, are a valuable tool for asynchronous programming since they mitigate, if not altogether remove, difficulties with callbacks like Callback Hell and Inversion of Control. On the other hand, async functions offer a more straightforward answer to these issues.

Let's see more about generator functions in JavaScript.

Generator Function in JavaScript

Read more about, Fibonacci Series in Java

What is Javascript Generator Function?

A generator function is defined identically to a regular function, except when it needs to generate a value, it uses the yield keyword instead of the return keyword. The yield statement halts the execution of a function and returns a value to the caller, but it keeps enough state for the function to restart where it left off. When the function is resumed, it continues where it left off after the last yield run.

Syntax of Generator Function in JavaScript

function* functionName(){
yield1;
yield2;
//statements
return;
}

Methods of JS Generator Function

There are three methods mainly associated with generators. 

  1. next(): It returns the value of yield.
  2. return(): It returns the value and then terminates the generator function.

throw(): It throws an error and then ends the generator function.

Working of Generator Function in JS

Let us see an example of a generator function and then understand its working.

Code

  • JS

JS

function* generator(a) {
 yield a;
 yield a + 5;
}

const gen = generator(2);

console.log(gen.next().value); // expected output: 2
console.log(gen.next().value); // expected output: 7
You can also try this code with Online Javascript Compiler
Run Code

Output

2
7

Explanation

When you call a generator function, its body is not immediately executed; instead, an iterator object for the function is returned. When the iterator's next() method is invoked, the generator function's body is executed until the first yield expression, which specifies the value to be returned from the iterator or, in the case of yield*, delegates to another generator function, is reached. 

The next() method produces an object that has a value property that contains the yielded value and a done property that is a boolean that indicates if the generator has yielded its last value. When you call the next() method with an argument, it will restart the execution of the generator function, substituting the yield expression that was interrupted with the argument from next ().

When a generator's return statement is invoked, the generator will end (i.e. the done property of the object returned by it will be set to true). If a value is returned, the value property of the object returned by the generator will be set to that value

An error thrown inside the generator, similar to a return statement, will finish the generator unless it is captured within the generator's body. When a generator is completed, further next() calls will not run any of its code; instead, they will return an object of the following form: {value: undefined, done: true}.

Examples of Generator Function

Let us see some more examples of generator functions.

Example 1 - Having yield* 

  • JS

JS

function* anotherGenerator(a) {
 yield a + 5;
 yield a + 10;
 yield a + 15;
}

function* generator(a) {
 yield a;
 yield* anotherGenerator(a);
 yield a + 50;
}

var g = generator(5);

console.log(g.next().value); // Print: 5
console.log(g.next().value); // Print: 10
console.log(g.next().value); // Print: 15
console.log(g.next().value); // Print: 20
console.log(g.next().value); // Print: 55
You can also try this code with Online Javascript Compiler
Run Code

Output

5
10
15
20
55

Example 2 - Passing arguments

  • JS

JS

function* logGenerator() {
 console.log(0);
 console.log(1, yield);
 console.log(2, yield);
 console.log(3, yield);
}

var g = logGenerator();

g.next();  // 0
g.next('Coding'); // 1 Coding
g.next('Ninjas');  // 2 Ninjas
g.next('Library'); // 3 Library
You can also try this code with Online Javascript Compiler
Run Code

Output

0
1 ‘Coding’
2 ‘Ninjas’
3 ‘Library’

Example 3 - Having Return statement 

  • JS

JS

function* yieldAndReturn() {
 yield "Yield";
 return "Return";
 yield "unreachable";
}

var g = yieldAndReturn();

console.log(g.next()); // { value: "Yield", done: false }
console.log(g.next()); // { value: "Return", done: true }
console.log(g.next()); // { value: undefined, done: true }
You can also try this code with Online Javascript Compiler
Run Code

Output

{value:'Yield', done: false}
{value:'Return', done: true}
{value:undefined, done: true}

Example 4 - Having Throw statement

  • JS

JS

function* yieldAndThrow() {
   yield 50;
   yield 70;
}

var g = yieldAndThrow();

console.log(g.next());
console.log(g.throw(new Error('An error found!!!')));
console.log(g.next());
You can also try this code with Online Javascript Compiler
Run Code

Output

{value:50, done: false}
       yield 50;
       ^
Error: An error found!!!

Example 5 - Generator example

  • JS

JS

function* powers(i){
    //infinite loop to calculate exponent
    for(let curr =i ; ; curr *= i){
        yield curr;
    }
}

for(let power of powers(2)){
    //controlling generator
    if(power > 64) break;
    console.log(power)
}
You can also try this code with Online Javascript Compiler
Run Code

Output

2
4
8
16
32
64

For better understanding try it on an online javascript editor.

How to Throw an Exception from a Generator Object?

In JavaScript, you can throw an exception from a generator object using the throw method. This method can be called on a generator to signal an error and can also be caught within the generator itself using a try-catch block. Below is a detailed explanation along with code implementation, expected output, and explanation.

  • JS

JS

function* generatorFunction() {
try {
// Yield a value
const value = yield "Generator started";
console.log("Received:", value);
} catch (error) {
// Catch the thrown error
console.log("Caught an error:", error.message);
}
}

const gen = generatorFunction();

// Start the generator
console.log(gen.next().value); // Output: "Generator started"

// Throw an exception into the generator
gen.throw(new Error("Something went wrong")); // Output: "Caught an error: Something went wrong"
You can also try this code with Online Javascript Compiler
Run Code

 

Output

Generator started
Caught an error: Something went wrong

Advantages of using the Generator Function

The advantages of using generator functions are:

  • Lazy Evaluation: This is an evaluation paradigm that waits until the value of an expression is required before evaluating it. In other words, if the value isn't needed, it won't exist. It is based on demand.
  • Efficient Memory: Generators are memory efficient as a direct result of Lazy Evaluation. Only the values that are required are created. All of the values for typical functions must be pre-generated and saved in case they are needed later. With generators, however, the calculation is postponed.

Disadvantages of Generator Function

Here are some disadvantages of generator functions in JavaScript:

  • Single Iteration: Generators can only be iterated once. Once a generator's execution is complete, it cannot be restarted or reused, which may require additional logic to handle repeated iterations over the same sequence of values.
  • Complexity in Error Handling: While generators can handle exceptions internally, managing errors and control flow across multiple yield points can complicate code readability and maintainability, especially in larger applications.
  • Performance Overhead: Using generators may introduce some performance overhead compared to traditional functions, particularly for simple operations, due to the context switching and state management involved in yielding and resuming execution.

Frequently Asked Questions

Define generator object.

A generator object is returned by generator functions. Calling the next method on the generator object or utilising the generator object in a "for of" loop are two ways to use generator objects. A generating function returns the Generator object, which is compliant with both the iterable and iterator protocols.

Describe yield and yield*.

  • yield: stops the generator from running and returns the value of the expression written after the yield keyword.
  • yield*: iterates through the operands, returning each value until done is true.

When should I use generators in JavaScript?

Generators should be used when managing asynchronous operations, such as fetching data in sequence or implementing complex iterators. They provide better control over the execution flow and allow yielding values on demand, improving code readability.

What is the difference between a generator function and a normal function in JavaScript?

A generator function can pause execution and yield multiple values over time, using the yield keyword, while a normal function executes entirely and returns a single value. Generators return an iterator that allows for stateful iteration.

Why do we need a generator function?

Generator functions are useful for creating iterators that can produce a sequence of values lazily, improving performance and memory efficiency. They simplify asynchronous programming patterns and allow for more elegant handling of complex workflows without blocking the main thread.

Conclusion

In this article, we learned about the Generator Function in JavaScript. Generator functions in JavaScript provide a powerful tool for managing asynchronous operations and creating custom iterators. By enabling the ability to pause and resume execution, they offer a more flexible and efficient approach to handling sequences of data. Generators enhance code readability and maintainability, especially when dealing with complex workflows or large datasets.

Recomended Articles

Live masterclass