How to sequentially chain two sync iterators in JavaScript?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If you want to iterate through one synchronous iterable and then continue with another, the simplest JavaScript answer is to use a generator. A chained generator stays lazy, works with for...of, and avoids copying values into a temporary array.
The Easiest Pattern: yield*
Generators are a natural fit because yield* delegates iteration to another iterable. To chain two iterables in sequence, yield from the first one and then from the second one.
The output is 1, 2, 3, a, b in that order. Nothing is eagerly combined. The next value is produced only when the consumer asks for it.
Why This Works for Sync Iterators
Any object that implements Symbol.iterator is iterable. Arrays, sets, strings, and generator results all fit this model. yield* simply forwards control to the next iterable until it is exhausted, then your generator continues with the following one.
That means the chaining function can stay generic. It does not need to know whether the input came from an array, a custom iterator, or another generator.
A Manual Iterator Version
If you want to see the mechanics more directly, you can implement the same behavior with an object that exposes next() and Symbol.iterator.
This version is more verbose, but it helps explain the underlying rule: consume the first iterator until it finishes, then switch to the second one.
Why Not Just Concatenate Arrays
If your inputs are definitely arrays, [...a, ...b] or a.concat(b) is perfectly fine. But those approaches create a new array immediately. Chaining iterators is more general and preserves lazy evaluation, which matters when values are expensive to produce or potentially large.
That is why generator-based chaining is often the best default for iterator-oriented code.
Iterables Versus Iterator Objects
Most examples use arrays and generators, which are iterables. If you already have raw iterator objects, wrap them or adapt the chaining function accordingly. The important rule is that the consumer needs a valid iterator protocol, and yield* works best when the input is iterable rather than just a bare object with next().
That makes the helper easier to reuse safely.
Common Pitfalls
- '
yield*expects an iterable, so passing a plain object withoutSymbol.iteratorwill fail.' - Chaining iterators is lazy, which is usually good, but it also means side effects happen only during consumption.
- If the first iterable throws during iteration, the second one is never reached.
- Array concatenation is simpler for small array-only cases, but it is not the same thing as iterator chaining.
Summary
- The simplest way to chain two synchronous iterables in JavaScript is a generator with
yield*. - That approach stays lazy and works with any iterable, not just arrays.
- A manual
next()implementation can do the same thing, but it is more verbose. - Use array concatenation only when eager materialization is acceptable and the inputs are definitely arrays.

