- Introduction to Generator Functions
- Basic Syntax
- Yielding Values
- Iterating with Generators
- Using Generators for Infinite Sequences
- Generator Function Arguments
- Delegating Generators
- Error Handling in Generators
- Practical Use Cases
- Comparison with Regular Functions
Generator functions are a special class of functions in TypeScript that can be paused and resumed, allowing you to work with lazy sequences and asynchronous programming more easily.
Defines the basic syntax for creating a generator function.
function* generatorFunction(): Generator<string> {
yield 'Hello';
yield 'World';
}
const gen = generatorFunction();
console.log(gen.next().value); // Hello
console.log(gen.next().value); // World
Demonstrates how to yield values from a generator function.
function* numberGenerator(): Generator<number> {
yield 1;
yield 2;
yield 3;
}
const numbers = numberGenerator();
console.log(numbers.next().value); // 1
console.log(numbers.next().value); // 2
console.log(numbers.next().value); // 3
Shows how to iterate over values yielded by a generator using a for...of
loop.
function* colorGenerator(): Generator<string> {
yield 'red';
yield 'green';
yield 'blue';
}
for (const color of colorGenerator()) {
console.log(color); // red, green, blue
}
Illustrates how to create an infinite sequence with a generator.
function* infiniteNumbers(): Generator<number> {
let i = 0;
while (true) {
yield i++;
}
}
const infiniteGen = infiniteNumbers();
console.log(infiniteGen.next().value); // 0
console.log(infiniteGen.next().value); // 1
console.log(infiniteGen.next().value); // 2
Shows how to pass arguments to a generator function.
function* idGenerator(start: number): Generator<number> {
let id = start;
while (true) {
yield id++;
}
}
const idGen = idGenerator(100);
console.log(idGen.next().value); // 100
console.log(idGen.next().value); // 101
Demonstrates how to delegate to another generator from within a generator.
function* subGenerator(): Generator<string> {
yield 'Sub 1';
yield 'Sub 2';
}
function* mainGenerator(): Generator<string> {
yield 'Main 1';
yield* subGenerator();
yield 'Main 2';
}
for (const value of mainGenerator()) {
console.log(value); // Main 1, Sub 1, Sub 2, Main 2
}
Shows how to handle errors within a generator function.
function* errorHandlingGenerator(): Generator<string> {
try {
yield 'Trying...';
throw new Error('An error occurred!');
} catch (e) {
yield `Caught an error: ${e.message}`;
}
}
const errorGen = errorHandlingGenerator();
console.log(errorGen.next().value); // Trying...
console.log(errorGen.next().value); // Caught an error: An error occurred!
Discusses practical use cases for generator functions, such as lazy evaluation and asynchronous workflows.
function* lazyEvaluator(arr: number[]): Generator<number> {
for (const num of arr) {
yield num * num;
}
}
const squares = lazyEvaluator([1, 2, 3, 4, 5]);
for (const square of squares) {
console.log(square); // 1, 4, 9, 16, 25
}
Highlights the differences between generator functions and regular functions, such as the ability to pause and resume execution, and yield multiple values over time.
function regularFunction(): number {
return 1;
}
function* generatorFunction(): Generator<number> {
yield 1;
yield 2;
yield 3;
}
const genFunc = generatorFunction();
console.log(regularFunction()); // 1
console.log(genFunc.next().value); // 1
console.log(genFunc.next().value); // 2
console.log(genFunc.next().value); // 3
This Gist was created with the assistance of ChatGPT.