JavaScript Function Generator (original) (raw)
Last Updated : 20 Jan, 2025
A generator function is a special type of function that can pause its execution at any point and resume later. They are defined using the function* syntax and use the yield keyword to pause execution and return a value.
**Syntax
function* generatorFunction() { // Code that can yield multiple values }
JavaScript `
function* generate() { yield 'Hello'; yield 'World'; return 'Done'; }
const generator = generate();
//Driver Code Starts{ console.log(generator.next()); console.log(generator.next()); console.log(generator.next()); console.log(generator.next()); //Driver Code Ends }
`
Output
{ value: 'Hello', done: false } { value: 'World', done: false } { value: 'Done', done: true } { value: undefined, done: true }
- The next() method is used to resume execution and retrieve the next value.
- The done property indicates whether the generator has finished executing.
How Do Generators Work?
Generators work by implementing the iterator protocol. When a generator function is called, it does not execute its body immediately. Instead, it returns a special iterator object called a generator object. This object can be used to control the execution of the generator.
- **Execution Control: The next() method resumes execution of the generator function until the next yield is encountered. It returns an object with two properties:
- **value: The yielded value.
- **done: A boolean indicating if the generator has completed execution.
- **State Preservation: Each call to next() resumes the function from where it was last paused, retaining the function’s state.
- **Termination: When the generator completes execution, the done property of the returned object becomes true. JavaScript `
function* example() { console.log("Step 1"); yield 1; console.log("Step 2"); yield 2; console.log("Step 3"); return 3; }
const gen = example();
//Driver Code Starts{ console.log(gen.next()); console.log(gen.next()); console.log(gen.next()); //Driver Code Ends }
`
Output
Step 1 { value: 1, done: false } Step 2 { value: 2, done: false } Step 3 { value: 3, done: true }
**Key Features of Generators
- **Pause and Resume: Generators allow pausing function execution using yield and resuming it with the next() method.
- **Iterable Interface: They return an iterator that conforms to the iterable protocol.
- **Asynchronous Support: Ideal for working with asynchronous tasks using for-await-of loops.
Use Cases for Generators
1. Custom Iterators
Generators simplify the creation of custom iterators, making it easy to generate sequences of values.
JavaScript `
function* fibonacci(limit) { let [prev, current] = [0, 1]; while (limit--) { yield current; [prev, current] = [current, prev + current]; } } const fib = fibonacci(5); console.log([...fib]);
`
2. Asynchronous Programming
Generators, in combination with libraries like co or with async/await syntax, help manage asynchronous flows.
JavaScript `
function* asyncTask() { console.log('Task 1'); yield new Promise(resolve => setTimeout(() => resolve('Task 2'), 1000)); console.log('Task 3'); } const task = asyncTask(); task.next().value.then(console.log); task.next();
`
**Output:
Task 1 Task 3 Task 2
3. Infinite Sequences
Generators can create infinite sequences that only compute values on demand.
JavaScript `
function* infiniteSeq() { let i = 0; while (true) { yield i++; } } const sequence = infiniteSeq();
console.log(sequence.next().value); //Driver Code Starts{ console.log(sequence.next().value); console.log(sequence.next().value); //Driver Code Ends }
`
Advantages of Generator Functions
- **Lazy Evaluation: Values are computed only when needed, improving performance for large or infinite sequences.
- **Readable Asynchronous Code: Generators can make asynchronous workflows look synchronous, simplifying complex code.
- **Modularity: Encapsulate logic for producing sequences or iterating over data within a generator.
- **Customizable Iterators: Generators allow creating iterators without implementing the entire iterable protocol manually.
Limitations of Generator Functions
- **Complexity: Understanding and debugging generator-based code can be challenging for beginners.
- **Not Fully Asynchronous: While useful, generators alone are not a replacement for promises or async/await in handling asynchronous programming.