Free tools Windows power users keep installed
One-click scans. No signup required.
A JavaScript generator function pauses at yield and continues only when its caller asks for another value. Writing it as function* and calling it creates a generator object—not an immediately running function result. Each call to next() resumes execution and returns an object with value and done fields.
What a generator function does
A generator function is a function that can suspend and resume its execution. The asterisk in function* marks the declaration:
function* countUpTo(limit) {
for (let value = 1; value <= limit; value++) {
yield value;
}
}
const iterator = countUpTo(3);
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 }
Calling countUpTo(3) creates a generator object, which remembers where execution is paused and the function’s local state. The body starts running when next() is called. Each call continues until the next yield or until the function finishes. The generator object follows the iterator and iterable protocols, so it works both with direct calls to next() and with constructs such as for...of and array spread. See MDN’s iterators and generators guide and function* reference.
How to read an iterator result
Every next() call returns an object with two fields:
#1 Best Overall
valueis the value yielded by the generator, or its final return value when it completes.doneisfalsewhile the generator can continue andtruewhen it has finished.
In the example, each yielded number arrives with done: false. Once the loop ends, the generator reports done: true; because the function did not explicitly return a value, the final value is undefined.
How yield pauses and resumes execution
The yield operator pauses the generator and makes the expression’s value available to the caller. When the caller resumes the generator, the suspended yield expression evaluates to the argument passed to next(). MDN describes yield as an operator used “to pause and resume a generator function” in its yield reference.
function* conversation() {
const answer = yield "What is your name?";
yield `Hello, ${answer}`;
}
const chat = conversation();
console.log(chat.next()); // { value: "What is your name?", done: false }
console.log(chat.next("Ada")); // { value: "Hello, Ada", done: false }
console.log(chat.next()); // { value: undefined, done: true }
The first next() starts the function and reaches the first yield, which produces the question. The next call passes "Ada" into that suspended yield expression, so answer becomes "Ada". This is why next() has two roles: its returned object carries a value out, while its optional argument sends a value in.
An argument to the first next() call is ignored. At that point the generator has not started and no suspended yield is waiting to receive it.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesRank #3
How yield* delegates to another iterable
Use yield* when a generator should pass through values from another iterable rather than yield them one by one itself. The outer generator delegates iteration to that iterable, which can be another generator:
function* first() {
yield "red";
yield "green";
}
function* allColors() {
yield* first();
yield "blue";
}
console.log([...allColors()]); // ["red", "green", "blue"]
Here, the spread syntax consumes allColors(), and the delegated colors appear in sequence before "blue". Delegation can also forward iterator operations to the delegated iterator. See MDN’s yield* reference.
Rank #4
How generators compare with ordinary functions and arrays
| Comparison | Generator | Ordinary function or eager array |
|---|---|---|
| Execution timing | A call creates a generator object; its body advances when the consumer requests values. | An ordinary function runs when called. An eager array’s values are already computed when the array is created. |
| What the consumer receives | Direct calls to next() return iterator-result objects with value and done. |
An ordinary function returns its result directly; an array stores its elements. |
| How values are produced | One at a time as requested; the generator retains its execution state between yields. | An array is built as a whole rather than generated on demand. |
This demand-driven behavior makes generators useful for sequences that are large, incremental, or potentially infinite. It does not establish a fixed speed or memory advantage: the practical result depends on the work being done and how the values are consumed.
Example: stop consuming an infinite sequence
function* integers() {
let value = 0;
while (true) yield value++;
}
for (const value of integers()) {
if (value === 3) break;
console.log(value);
}
The generator can describe an unbounded sequence without creating an unbounded array. The loop requests values as it runs and stops when it reaches 3, so it never asks the generator for later values.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Best Value
How return() and throw() control a generator
Generator objects expose next(), return(), and throw(). These are iterator control methods, not ways to restart a generator.
return(value)requests completion as if a return were inserted at the generator’s suspended position.throw(error)injects an error at the suspended position. Generator code can catch it, or it can escape to the caller.
A try...finally block can run cleanup when a generator is closed:
function* withCleanup() {
try {
yield "working";
} finally {
console.log("cleanup");
}
}
const task = withCleanup();
task.next();
task.return(); // runs finally before closing
After a generator has completed, it does not resume producing later yields.
How async generators differ
An async generator is declared with async function*. Unlike a regular generator, its next() method returns a promise that resolves to an iterator result. Consume its values with for await...of:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
async function* pages() {
yield "page one";
yield "page two";
}
for await (const page of pages()) {
console.log(page);
}
The async keyword marks a distinct generator form; a regular function* is not automatically asynchronous. The behavior described here follows the JavaScript language references maintained by MDN and the Generator reference; the normative language specification checked is Ecma International’s ECMA-262, 16th edition, published June 2025. MDN’s yield and yield* pages report a last modification date of July 8, 2025.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

