Suggest an editImprove this articleRefine the answer for “Generator functions”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A generator function is a special kind of function that can pause its own execution and later resume it from exactly the same place.** You declare it with `function*` and use `yield` inside it to hand out values one at a time. Calling such a function does not run its body straight away: it returns a generator object that follows the iterator protocol, so you can walk it with `next()` or with `for...of`. ```javascript function* gen() { yield 1; yield 2; } const it = gen(); console.log(it.next()); // { value: 1, done: false } console.log(it.next()); // { value: 2, done: false } console.log(it.next()); // { value: undefined, done: true } ``` **Key point:** generators give you lazy evaluation, custom iterators and step by step control over execution, and `async function*` brings the same thing to asynchronous data streams.Shown above the full answer for quick recall.Answer (EN)Image**A generator function is a function that can pause its own execution and then continue from exactly the same place.** It returns a generator object and hands out values one at a time through `yield`, which makes it a convenient base for iterators, lazy evaluation and asynchronous loops. ## Theory ### TL;DR - The declaration looks like `function* name() {}`: the asterisk after `function` makes it a generator. - Calling it does not run the body, it returns a generator object (an iterator) with a `next()` method. - `yield` hands out a value and freezes execution; the next `next()` resumes from the same line. - A generator follows the iterator protocol, so it works in `for...of`, in spread and in destructuring. - `next(value)` passes a value back into the generator, so the exchange goes both ways. - `async function*` together with `for await...of` brings the same thing to asynchronous streams (ES2018). ### Quick example ```javascript function* gen() { yield 1; yield 2; yield 3; } const iterator = gen(); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true } ``` What happens here: - the first `next()` call runs up to the first `yield`, returns `1` and freezes the function; - the following `next()` resumes execution from the very same place; - after the last `yield` the generator finishes its work and reports `done: true`. ### Syntax and the generator object A generator function is a function that returns a generator object (an iterator) and uses the `yield` keyword inside itself to pause execution and return values one by one. ```javascript function* name(args) { // function body } ``` - `*` after `function` turns the function into a generator; - `yield` is used to hand out values step by step; - when called, the function does not run immediately, it returns a generator (an iterator). Every `next()` call returns an object shaped like `{ value, done }`, where `value` is whatever `yield` produced and `done` tells you whether the generator has already finished. ### Generators are iterators A generator returns an object that is compatible with the iterator protocol. That means you can pass it straight into `for...of`: ```javascript function* numbers() { yield 10; yield 20; yield 30; } for (const n of numbers()) { console.log(n); } ``` Output: ```javascript 10 20 30 ``` The same generator also works with the spread operator (`[...numbers()]`) and with array destructuring. ### Lazy evaluation and infinite sequences Generators can be infinite: they do not build the whole array up front, they produce values on demand. That is lazy evaluation, values are generated only as they are needed. ```javascript 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 // ...and so on forever ``` The same approach is handy for finite sequences you would rather not materialise into an array: ```javascript function* range(start, end, step = 1) { for (let i = start; i <= end; i += step) { yield i; } } for (const num of range(1, 5)) { console.log(num); } ``` Output: ```javascript 1 2 3 4 5 ``` ### Two way exchange: next(value) and return Data can travel not only out of the generator but back into it, through the argument of `next(value)`. That argument becomes the result of the `yield` expression the generator is currently paused on. ```javascript function* dialog() { const name = yield 'What is your name?'; yield `Hello, ${name}!`; } const it = dialog(); console.log(it.next().value); // "What is your name?" console.log(it.next('Maria').value); // "Hello, Maria!" ``` The first `next()` only starts the generator and runs it to the first `yield`, the second one passes `'Maria'` inside as the result of that `yield` expression. You can finish a generator early with `return`: ```javascript function* example() { yield 1; return 'end'; yield 2; // never runs } const it = example(); console.log(it.next()); // { value: 1, done: false } console.log(it.next()); // { value: 'end', done: true } ``` ### Async generators and where all of this is used Async generators (ES2018) let you use `await` inside iterable streams of data. You walk them with `for await...of`. ```javascript async function* fetchData() { yield await Promise.resolve('First chunk'); yield await Promise.resolve('Second chunk'); } for await (const part of fetchData()) { console.log(part); } ``` What generators are actually good for: | Use case | Example | | --- | --- | | Building iterators | Producing data element by element | | Lazy evaluation | No need to keep the whole array in memory | | Step by step execution | Controlling the flow of execution | | Asynchronous pipelines | Processing data streams without loading memory | | Emulating coroutines | The ability to stop and resume code | A summary of the syntax and the capabilities: | Property | Description | | --- | --- | | Definition | A function declared with `function*` that returns an iterator | | Returns | A generator object | | Keyword | `yield` | | Can pause execution | Yes | | Can take values back in | Yes | | Asynchronous version | `async function*` | | Main use | Lazy evaluation, iterators, asynchronous streams | ### Common mistakes - **Thinking that calling a generator runs its body.** `gen()` only creates a generator object; not a single line of the body runs until you call `next()`. - **Confusing `yield` with `return`.** `return` finishes the generator: everything after it is never handed out, and the returned value arrives together with `done: true`. - **Expecting the first `next(value)` to pass a value inside.** The first call only runs the body up to the first `yield`, so its argument is ignored. - **Walking an infinite generator with `for...of` and no `break`.** The loop will never end, you need an explicit limit. - **Using `for...of` instead of `for await...of` with `async function*`.** You will get promises back rather than the values themselves. - **Reusing an exhausted generator.** Once it reports `done: true` it does not restart: you have to call the generator function again and get a fresh object.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.