Leaderboard
Javascript Apr 24, 2026
Javascript Generator Yield Next

JS Generator Function - What does next().value print twice?

This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Generator Yield Next and improve your technical interview readiness.

function* gen() {
  yield 1
  yield 2
  yield 3
}
const g = gen()
console.log(g.next().value)
console.log(g.next().value)
A 1, 1
B 1, 2
C undefined, undefined
D 1, undefined

Detailed Explanation

Why This Question Matters

If you've spent any time with modern JavaScript, you've probably seen the function* syntax. Generators are one of those features that feel "magic" until they suddenly click. Most developers treat them as a niche curiosity or something only used inside libraries like Redux-Saga, but they actually solve a very specific problem: controlling the execution of a function.

The confusion usually stems from the fact that generators don't behave like regular functions. A normal function runs from top to bottom and returns a value. A generator, however, is a state machine. It pauses and resumes. If you don't understand how the iterator protocol works, you'll likely guess the wrong answer to this challenge because you're thinking in terms of standard function calls, not state transitions.

Understanding the Code

Let's look at the snippet:

function* gen() {
  yield 1
  yield 2
  yield 3
}
const g = gen()
console.log(g.next().value)
console.log(g.next().value)

First, notice the asterisk in function*. This tells JavaScript that this isn't a standard function; it's a generator function. When you call gen(), it doesn't actually execute the code inside the block. Instead, it returns a Generator Object.

Think of this object as a pointer. It knows exactly where the function is currently paused.

When we call g.next(), we're telling the engine: "Run the code until you hit the next yield keyword, then stop and give me the value."

Here is the internal play-by-play:

1. const g = gen(): We initialize the generator. The function is now "primed" but hasn't started running yet.
2. First g.next().value: The engine enters the function and runs until it hits yield 1. It pauses there and returns an object: { value: 1, done: false }. We access .value, so 1 is printed.
3. Second g.next().value: The engine resumes exactly where it left off. It doesn't restart from the top. It moves from the first yield to the second one: yield 2. It pauses again and returns { value: 2, done: false }. Thus, 2 is printed.

Finding the Correct Answer

The correct answer is Option B (1 and 2).

Why not other options?

- Why not 1 and 1? Because the generator maintains its state. It doesn't reset every time you call .next(). It remembers it already passed the first yield.
- Why not 1 and 3? The generator moves sequentially. It cannot skip yield 2 unless you explicitly call .next() multiple times.
- Why not undefined? The value property is explicitly set by the yield keyword.

If we called g.next().value a third time, we'd get 3. A fourth time? We'd get undefined because the function would finish, and the return object would be { value: undefined, done: true }.

Common Mistakes Developers Make

The biggest mistake is assuming gen() executes the body immediately. If you write a console.log inside the generator function but outside a yield, you'll notice it doesn't print until you call .next().

Another trip-up is forgetting that generators are single-use. Once a generator has been exhausted (i.e., it reached the end of the function), you can't "restart" it. If you need to iterate again, you have to create a new generator instance by calling gen() again.

Lastly, people often confuse generators with arrays. While you can loop over a generator using for...of, a generator doesn't store all its values in memory. It calculates the next value on the fly. This is a massive advantage for performance when dealing with large datasets.

Real-World Usage

You might be wondering, "Why would I ever use this instead of a simple array or a loop?"

The killer feature here is lazy evaluation. Imagine you have a dataset of 10 million records, and you need to process them one by one. If you put them in an array, you'll crash your browser's memory. With a generator, you only ever have one record in memory at a time.

In production, you'll see this in:

1. Custom Iterables: Creating a data structure that can be looped over without exposing the internal storage.
2. Async Flow Control: Before async/await became the standard, generators (combined with promises) were used to write asynchronous code that looked synchronous.
3. Infinite Sequences: You can write a generator that produces an infinite sequence of IDs or Fibonacci numbers without causing a stack overflow, because it only produces the next value when requested.

Key Takeaways

- A generator function returns an iterator, not a value.
- yield is a pause button. It tells the function to stop and hand a value back to the caller.
- .next() is the play button. It resumes execution until the next yield or the end of the function.
- Generators maintain their internal state, making them perfect for handling streams of data or complex state machines without polluting the global scope.

Why this matters

Understanding Generator Yield Next is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.

📝
Reviewed by CodeShot Editorial
Every challenge is code-reviewed by senior developers to ensure accuracy and real-world relevance. Learn more.

Ready for your shot?

Join thousands of developers solving one logic puzzle every morning.

Solve Today's Challenge →