JavaScript Generators

JavaScript Generators

JavaScript Generators

Generators are special functions in JavaScript that can be paused and resumed, making them useful for handling asynchronous tasks, infinite sequences, and memory-efficient iteration.

🔹 1. What is a Generator?

A generator function is defined using function* (with an asterisk * after function) and uses the yield keyword to pause execution.

🔹 Basic Syntax

function* generatorFunction() { yield "Hello"; yield "World"; return "End"; } const generator = generatorFunction(); console.log(generator.next()); // { value: "Hello", done: false } console.log(generator.next()); // { value: "World", done: false } console.log(generator.next()); // { value: "End", done: true } console.log(generator.next()); // { value: undefined, done: true }

Each yield pauses execution and returns a value.
Calling next() resumes execution from the last yield.
When return is reached, done: true indicates completion.

🔹 2. Iterating Over a Generator

Generators are iterable, meaning you can use them in a for...of loop.

function* generatorFunction() { yield "🚀"; yield "🌍"; yield "🌟"; } for (let value of generatorFunction()) { console.log(value); } // Output: 🚀 // 🌍 // 🌟

Looping stops automatically when done: true.

🔹 3. Infinite Generators

Since generators pause execution, they are great for infinite sequences without blocking memory.

function* infiniteCounter() { let i = 1; while (true) { yield i++; } } const counter = infiniteCounter(); console.log(counter.next().value); // 1 console.log(counter.next().value); // 2 console.log(counter.next().value); // 3 // ... continues forever!

✔ Unlike an infinite loop, this does not block execution.

🔹 4. Generator with Arguments

You can pass arguments to next() to send values back into the generator.

function* customCounter() { let count = 0; while (true) { count += yield count; } } const counter = customCounter(); console.log(counter.next().value); // 0 console.log(counter.next(5).value); // 5 (adds 5) console.log(counter.next(3).value); // 8 (adds 3)

The value passed to next(value) is received inside the generator as yield's result.


🔹 5. Delegating Generators (yield*)

A generator can delegate to another generator using yield*.

js
function* firstGenerator() { yield "👋"; yield "Hello"; } function* secondGenerator() { yield* firstGenerator(); yield "World"; } const gen = secondGenerator(); console.log([...gen]); // ["👋", "Hello", "World"]

yield* includes all values from another generator.

🔹 6. Error Handling in Generators

Errors can be thrown inside a generator using throw().

function* generatorFunction() { try { yield "Step 1"; yield "Step 2"; } catch (error) { console.log("Caught:", error); } } const gen = generatorFunction(); console.log(gen.next()); // { value: "Step 1", done: false } console.log(gen.throw(new Error("Something went wrong"))); // "Caught: Error: Something went wrong" console.log(gen.next()); // { value: undefined, done: true }

Errors can be handled inside the generator.

🔹 7. Async Generators (async function*)

An async generator allows await inside and produces asynchronous values.

async function* asyncNumbers() { for (let i = 1; i <= 3; i++) { await new Promise(resolve => setTimeout(resolve, 1000)); yield i; } } (async () => { for await (let num of asyncNumbers()) { console.log(num); // Prints 1, 2, 3 with 1-second delays } })();

Useful for streaming data asynchronously.

🔹 8. Summary

Generators (function*) allow pausing/resuming execution.
Use yield to pause, and next() to resume.
They are memory-efficient and great for infinite sequences.
Use yield* to delegate to another generator.
Use throw() inside a generator to handle errors.
async function* allows working with async data streams.

🚀 Generators provide powerful control over execution flow!

Soeng Souy

Soeng Souy

Website that learns and reads, PHP, Framework Laravel, How to and download Admin template sample source code free.

Post a Comment

CAN FEEDBACK
close