JavaScript - Generator

JavaScript - Generator

ยท

3 min read

What is Generator?

A JavaScript generator is a special type of function that allows you to generate a sequence of values, one at a time, using the yield keyword. Unlike regular functions that run to completion and return a single value, generators can pause their execution and later resume it from where it left off. This unique ability to pause and resume execution makes generators a powerful tool for handling asynchronous operations, iterating over large datasets, and implementing custom iterators.

function* myGeneratorFunction(num) {
    // Generator logic with yield statements
    for (let i = 0; i < num; i++) {
        yield `value ${i} was generated`;
    }
}

const generator = myGeneratorFunction(5);
console.log(generator.next());
// { value: 'value 0 was generated', done: false }
console.log(generator.next());
// { value: 'value 1 was generated', done: false }
console.log(generator.next());
// { value: 'value 2 was generated', done: false }

Usages

  • Data Generation: When dealing with large datasets, generators can be used to lazily generate and process data on-the-fly, rather than creating all the data upfront. This approach helps save memory and improves performance. For example, generating and processing data from a CSV file line by line.
  • Asynchronous Operations: Generators can be used in combination with Promises or async/await to handle asynchronous operations in a more readable and sequential manner. This is especially useful when dealing with multiple asynchronous tasks that need to be executed in a specific order.

This code demonstrates the power of combining generator functions with asynchronous operations. We use an async function, fetchApiData(url), to fetch data from a given URL using fetch. If there's a network error, it throws an 'Error' with the message 'Network response was not ok', otherwise, it returns the JSON response.

Next, we have a generator function, dataGenerator(apiUrls), which takes an array of API URLs. The generator iterates through the URLs using a 'for...of' loop, yielding the results of the fetchApiData calls.

We also have an async function, runGenerator(generator), that runs the generator and prints the results sequentially. It uses generator.next() to get the next value, waits for the Promise to resolve using await, and then logs the result using console.log. The function continues until next.done is true.

async function fetchApiData(url) {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error("Network response was not ok");
    }
    return response.json();
}

function* dataGenerator(apiUrls) {
    for (const url of apiUrls) {
        yield fetchApiData(url);
    }
}

async function runGenerator(generator) {
    const next = generator.next();
    if (!next.done) {
        try {
            const result = await next.value;
            console.log(result);
            await runGenerator(generator);
        } catch (error) {
            console.error("Error:", error.message);
        }
    }
}

const apiUrls = [
    "https://jsonplaceholder.typicode.com/posts",
    "https://jsonplaceholder.typicode.com/users",
    "https://jsonplaceholder.typicode.com/comments",
    "https://jsonplaceholder.typicode.com/todos",
];

const generator = dataGenerator(apiUrls);
runGenerator(generator);

Recap

From this, I've learned that JavaScript generators employ the yield keyword to create sequences of values, uniquely capable of pausing and resuming execution. The code example illustrates generating messages using a generator. It also showcases how generators work with async functions, fetching data in sequence from different URLs.

I've also included a couple of links below that offer further insight into how generators function and explore some practical use cases.

Resources

MDN - Generator function

Use-Cases For JavaScript Generators

Use case: simpler asynchronous code

Web Dev Simplified - Learn JavaScript Generators In 12 Minutes

Thank you!

Thank you for your time and for reading this!

Originally published at victoriacheng15.vercel.app

Did you find this article valuable?

Support Victoria's Blog by becoming a sponsor. Any amount is appreciated!

ย