Suggest an editImprove this articleRefine the answer for “What a generator call returns”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Calling a generator function (`function*`) does not run its code right away: it returns a generator object, which is an iterator and controls the execution of that function.** This object is not the result of a computation, it is a controller that lets you run the generator step by step through `.next()`, `.throw()` and `.return()`. ```javascript function* gen() { yield 1; yield 2; } const iterator = gen(); console.log(iterator); // Object [Generator] {} console.log(iterator.next()); // { value: 1, done: false } console.log([...gen()]); // [1, 2] ``` **Key point:** a generator returns an iterator, not a value; to get the values you have to walk it with `.next()`, `for...of`, spread or `Array.from`.Shown above the full answer for quick recall.Answer (EN)Image**Calling a generator function (`function*`) does not run its code right away: it returns a generator object, which is an iterator and controls the execution of that function.** In other words you get back not a result but a means of running the function body in portions. ## Theory ### TL;DR - `gen()` does not execute a single line of the body, it creates a generator object. - That object is an iterator: it has `.next()`, `.throw()` and `.return()`. - At the same time it is an iterable, because it has `[Symbol.iterator]()`. - Every `.next()` returns `{ value, done }` and runs execution up to the next `yield`. - To get all the values at once you have to walk the generator: `for...of`, spread, `Array.from`. - A generator is not the result of the function: `numbers()` is not `[1, 2]`. ### Quick example ```javascript function* gen() { yield 1; yield 2; yield 3; } const iterator = gen(); // a generator object comes back console.log(iterator); // Object [Generator] {} ``` The `iterator` object is not the function's result, it is a controller that lets you run the generator step by step through `.next()`, `.throw()`, `.return()`. ### The two protocols a generator implements A generator object implements two protocols at once: 1. **The iterator protocol**: a `next()` method that returns an object with `value` and `done` fields. 2. **The iterable protocol**: a `[Symbol.iterator]()` method that returns the generator itself. That is exactly why the same object can be cranked by hand with `.next()` and also handed to `for...of`. ```javascript function* gen() { yield 'A'; yield 'B'; } const it = gen(); console.log(it.next()); // { value: 'A', done: false } console.log(it.next()); // { value: 'B', done: false } console.log(it.next()); // { value: undefined, done: true } ``` Every `.next()` call: - starts the generator, if it is frozen; - runs it up to the next `yield` or `return`; - returns an object `{ value, done }`. ### A generator in for...of, spread and Array.from Because a generator is iterable, you can use it anywhere an iterable is expected: ```javascript function* gen() { yield 1; yield 2; yield 3; } const iterator = gen(); for (const n of iterator) { console.log(n); } ``` Output: ```javascript 1 2 3 ``` `[...gen()]` and `Array.from(gen())` work the same way. One caveat: walking a generator exhausts it, so a second `for...of` over the same object produces nothing, you need a fresh `gen()` call. ### The three methods of a generator object | Method | What it does | | --- | --- | | `.next(value)` | Resumes execution up to the next `yield`; returns `{ value, done }` | | `.throw(error)` | Raises an exception inside the generator (caught with `try/catch`) | | `.return(value)` | Finishes the generator and returns `{ value, done: true }` | ### A generator is not the function's result This is the part people forget most often: ```javascript function* numbers() { yield 1; yield 2; } const result = numbers(); // returns a generator object, not [1, 2] ``` To get the real values you have to walk the generator: ```javascript console.log([...numbers()]); // [1, 2] ``` or call `.next()` by hand a few times. Visually it looks like this: ```javascript ┌─────────────────────┐ │ function* numbers() │ │ { yield 1; yield 2; }│ └────────┬────────────┘ │ call ▼ ┌───────────────────────────────┐ │ Object [Generator] │ │ ├── next() │ │ ├── throw() │ │ ├── return() │ │ └── [Symbol.iterator]() │ └───────────────────────────────┘ ``` Summary: | What a generator returns | A generator object | | --- | --- | | Does it start immediately? | No | | Can you control execution? | Yes, through `.next()` | | Does it implement the iterator protocol? | Yes | | How does it return values? | Through `yield` | | Can it be used in `for...of` | Yes | | How does it return a final value | Through `return`, together with `done: true` | ### Common mistakes - **Expecting an array.** `numbers()` returns a generator object, not `[1, 2]`; spread or `Array.from` gives you the array. - **Assuming the body has already run.** Even a `console.log` at the top of the generator will not fire until the first `.next()`. - **Walking the same generator object twice.** After `done: true` it is exhausted; to go through it again, call the generator function once more. - **Confusing yielded values with the returned value.** Whatever `return` produces arrives together with `done: true` and never shows up in `for...of`. - **Forgetting that `.return()` finishes the generator for good.** Subsequent `.next()` calls only hand back `{ value: undefined, done: true }`. - **Checking `typeof gen()`.** It is always `'object'`, so testing the type that way is pointless; what marks a generator is having `next` and `[Symbol.iterator]`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.