DEV Community

francesco agati
francesco agati

Posted on

Generators in JavaScript

Generators in JavaScript are a powerful feature introduced in ECMAScript 6 (ES6) that allow you to define iterative algorithms by pausing and resuming execution at defined points. They provide a flexible way to control iteration and asynchronous operations.

How Generators Work

Generators are defined using function* syntax (note the asterisk). They use the yield keyword to pause execution and return values sequentially. When called, a generator function returns an iterator object that can be used to control the iteration.

Let's explore some practical examples to understand how generators are used:

Example 1: Fibonacci Sequence Generator

function* fibonacciGenerator() { let prev = 0; let curr = 1; yield prev; yield curr; while (true) { let next = prev + curr; yield next; prev = curr; curr = next; } } // Usage const fibonacciSequence = fibonacciGenerator(); for (let i = 0; i < 10; i++) { console.log(fibonacciSequence.next().value); // Outputs: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 } 
Enter fullscreen mode Exit fullscreen mode

In this example, fibonacciGenerator generates an infinite sequence of Fibonacci numbers, pausing after each yield statement until next() is called again.

Example 2: Inorder Traversal of a Binary Tree

class Node { constructor(value) { this.value = value; this.left = null; this.right = null; } } function* inorderTraversal(node) { if (node !== null) { yield* inorderTraversal(node.left); // Traverse left subtree yield node.value; // Yield current node's value yield* inorderTraversal(node.right); // Traverse right subtree } } // Usage const rootNode = new Node(10); rootNode.left = new Node(5); rootNode.right = new Node(15); // (Set up the rest of the tree as in the example) const iterator = inorderTraversal(rootNode); const result = []; for (let value of iterator) { result.push(value); } console.log(result); // Outputs: [3, 5, 7, 10, 15, 18] 
Enter fullscreen mode Exit fullscreen mode

This generator function performs an inorder traversal of a binary tree, yielding values in the correct order.

Example 3: Custom Iterator Using Generators

class Range { constructor(start, end) { this.start = start; this.end = end; } *[Symbol.iterator]() { for (let i = this.start; i <= this.end; i++) { yield i; } } } // Usage const range = new Range(1, 5); for (let num of range) { console.log(num); // Outputs: 1, 2, 3, 4, 5 } 
Enter fullscreen mode Exit fullscreen mode

Here, the Range class uses a generator to create an iterable range of numbers from start to end.

Example 4: Asynchronous Control Flow

function fetchDataFromAPI(endpoint) { return new Promise((resolve, reject) => { setTimeout(() => { const data = { endpoint, results: [1, 2, 3, 4, 5] }; resolve(data); }, Math.random() * 1000); }); } function* fetchAndProcessData() { try { const data1 = yield fetchDataFromAPI('/api/data1'); console.log('Processed data1:', data1); const data2 = yield fetchDataFromAPI('/api/data2'); console.log('Processed data2:', data2); const data3 = yield fetchDataFromAPI('/api/data3'); console.log('Processed data3:', data3); console.log('All data processed!'); } catch (error) { console.error('Error:', error); } } function runGenerator(generator) { const iterator = generator(); function iterate(iteration) { if (iteration.done) { return iteration.value; } const promise = iteration.value; return promise.then((value) => iterate(iterator.next(value))) .catch((error) => iterator.throw(error)); } return iterate(iterator.next()); } // Usage runGenerator(fetchAndProcessData); 
Enter fullscreen mode Exit fullscreen mode

This example demonstrates using a generator to manage asynchronous operations sequentially, yielding promises and processing their results.

Conclusion

Generators offer a flexible way to control iteration and manage asynchronous flows in JavaScript. By pausing execution with yield, they allow complex tasks to be handled in a more readable and sequential manner. Understanding generators enhances your ability to write efficient and expressive JavaScript code.

Top comments (0)