Getting Started With Generators in JS
Cover art created by the author using a base image generated by DALLE

Getting Started With Generators in JS

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.

Illustration of the working concept of a JS generator

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        
Output of the executed code

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.

Generator’s Next Object States

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        
Output of the execution

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.


要查看或添加评论,请登录

Parthipan N.的更多文章

社区洞察

其他会员也浏览了