Generator.prototype.next()

Resume a generator until its next yield and return a { value, done } result object.

Signature
next()
next(value)
  • Added in JavaScript ES2015 (ES6)

Parameters

ParameterTypeDescription
$valueoptionalanyA value to send into the generator. It becomes the result of the yield expression the generator is currently suspended at — in `variable = yield expression`, this value is assigned to variable. Ignored by the first next() call, since no yield is pending yet.

Return value

ObjectAn object with two properties: value, the value yielded or returned by the generator, and done, a boolean that is false while the generator can still produce values and true once it is past the end of its control flow.

Errors

Throws a TypeError if the generator is already running — that is, if next() is called from inside the generator's own body.

next() is the crank handle of a generator. Each call resumes the body from its last yield, runs until the following yield, return, or the end of the function, and reports the outcome as { value, done }. It is the same method for...of, spread and the iterator helpers all call under the hood.

When to reach for it

  • Pulling one value at a time, when a loop would consume too much.
  • Feeding values into a generator, which is the only way to use the two-way channel yield provides.
  • Inspecting done and the final return value, which for...of silently discards.

What trips people up

A return statement's value arrives with done: true, and for...of throws it away — only manual next() ever sees it. Once done is true, further calls return { value: undefined, done: true } forever; generators do not restart.

The argument to the first next() is discarded, because there is no suspended yield to receive it. Priming with a bare next() before sending real values is the standard workaround.

Calling next() on a generator from inside its own body throws a TypeError: a generator cannot be re-entered while it is running.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Pull values one at a time from an expensive or infinite generator
  • Push configuration or results back into a generator through yield
  • Read a generator's return value, which for...of discards

Frequently asked questions

What do value and done mean in the object next() returns?

value is whatever the generator just yielded, or its return value on the final call, and done is false while more values can be produced and true once the body has finished. When done is true and there was no return statement, value is undefined.

How do I pass a value into a generator?

Call next(value); it becomes the result of the yield expression the generator is suspended at, as in const x = yield something. The first next() cannot deliver a value because no yield is pending yet, so prime the generator with a bare next() before sending real data.

Why does next() return undefined after my generator finished?

Because a completed generator stays completed and returns { value: undefined, done: true } for every subsequent call. Generators cannot be reset or rewound — call the generator function again to get a fresh one with its own state.

More examples

The value/done shape across a full run

The return value rides along with done: true, so a consumer that stops at done never sees it — the spread produces only the two yielded strings. After completion the generator permanently reports { value: undefined, done: true }.

Example · javascript
function* gen() {
  yield "a";
  yield "b";
  return "finished";
}

const g = gen();
console.log(g.next()); // { value: 'a', done: false }
console.log(g.next()); // { value: 'b', done: false }
console.log(g.next()); // { value: 'finished', done: true }
console.log(g.next()); // { value: undefined, done: true }

console.log([...gen()]); // ['a', 'b'] — return value dropped

Re-entering a running generator throws

A generator has one execution context, so calling next() while it is mid-execution is rejected with a TypeError rather than corrupting its state. The same applies to indirect re-entry through a callback the generator invokes.

Example · javascript
function* selfCall() {
  yield g.next(); // re-enters itself
}

const g = selfCall();
try {
  g.next();
} catch (err) {
  console.log(err.constructor.name); // "TypeError"
  console.log(err.message); // engine-specific: generator is already running
}

Discussion

  • Be the first to comment on this lesson.