Getting Started With Generators in JS
Parthipan N.
Full-stack Developer | JavaScript | TypeScript | Python | MERN | AWS | PostgreSQL
A Hands-on Guide to Writing Your First Generator Function in JavaScript
Generators in JavaScript are a powerful feature introduced in ECMAScript 2015 (ES6) that allows a function to yield multiple values over time, pausing its execution between each yield and resuming it when required.
Unlike regular functions that complete entirely upon invocation, generators are designed to be paused and resumed, making them immensely useful for a variety of asynchronous operations and large data processing tasks.
In this brief article, let’s look into what generators are in Javascript and learn to create our first one through relevant code snippets. So, let’s get started.
What Makes Generators Unique?
A generator function, denoted by the function* syntax (a function keyword followed by an asterisk), works hand in hand with the yield keyword. Each time a yield is encountered, the generator function pauses, emitting the value specified by yield. This pausing and resuming capability fundamentally changes how we can control the execution flow in JavaScript.
Step 1: Writing a Generator Function
A generator function is defined using the function* syntax. Here’s how we can create a simple generator function:
function* simpleGenerator() {
yield 'Hello';
yield 'World';
}
In this example, simpleGenerator is a generator function that yields two values, Hello and World.
Step 2: Iterating Over a Generator
To use the generator, first, we need to instantiate it, which creates a generator object. This object adheres to both the iterable and iterator protocols.
const myGenerator = simpleGenerator();
Now, let’s iterate over the generator:
领英推荐
console.log(myGenerator.next().value);
// Output: Hello
console.log(myGenerator.next().value);
// Output: World
console.log(myGenerator.next().value);
// Output: undefined
Each call to myGenerator.next() resumes the generator function’s execution up to the next yield. When the generator has no more values to yield, it returns an object with value as undefined and done as true.
Practical Usage
Generators are particularly useful when dealing with sequences of data. They allow you to define potentially infinite data sequences without worrying about the memory constraints of storing them all at once.
Code Sample: Generating an Infinite Sequence
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}
const sequence = infiniteSequence();
console.log(sequence.next().value);
// Output: 0
console.log(sequence.next().value);
// Output: 1
// ...and so on
This generator function generates an infinite sequence of numbers. Despite the infinite loop, it doesn’t cause a memory overflow or stall our main thread because the values are yielded one at a time.
The key thing to note here is the lazy execution of the infinite loop, which was made possible by the generator and its iterator object.
Conclusion
Generators give us a new flexible way to orchestrate asynchronous operation while controlling the execution flow as we need it. On top of it, it makes lazy evaluations possible, which might come in handy when dealing with large datasets.
This article was originally published in my Medium Blog.