v146 · JavaScript · Iterators

Iterator Sequencing

Chrome 146 ships Iterator.concat(), a TC39 stage-3 proposal that creates a new iterator by sequencing multiple existing iterables one after another. Unlike Array.prototype.flat() or spread syntax, it is lazy — elements from each source are only pulled when consumed, with no intermediate array allocation.

concepts

  1. Iterator.concat() Demo

    Concatenate arrays, Sets, generator functions, and Map entries into a single lazy sequence using Iterator.concat(). Compare against the spread-into-array approach to see the difference in allocation.

  2. Practical Patterns

    Real-world patterns: merging search results from multiple sources, combining log streams, and processing heterogeneous data collections — all without creating intermediate arrays.

  3. Lazy pipeline builder

    Toggle finite, infinite and heterogeneous sources, chain iterator helpers and pick lazy vs eager. The runner reports per-source pull counts and warns when eager spread would hang.

  4. Pull trace

    Slide a take(n) dial and watch which cells get pulled, delivered, or skipped across three concatenated sources — direct visual proof that Iterator.concat() never enters the infinite tail unnecessarily.

why it shipped

Combining multiple iterable sources into one sequence has historically required spreading into an array ([...a, ...b, ...c]) or chaining with Lodash/Ramda. Both approaches are eager: they allocate a new array and materialise all elements upfront. Iterator.concat() is lazy — it returns an iterator object that pulls one element at a time from each source in sequence. This matters for large or infinite iterables (streams, generator chains), where eager materialisation would be prohibitively expensive or impossible. It also composes naturally with the rest of the TC39 iterator helpers: Iterator.concat(a, b).map(fn).take(10).

the API

// Basic usage — arrays are iterable
const seq = Iterator.concat([1, 2], [3, 4], [5, 6]);
console.log([...seq]); // [1, 2, 3, 4, 5, 6]

// Works with any iterable: Set, Map, generator, string
const merged = Iterator.concat(
  new Set(['a', 'b']),
  'cd',                          // string
  (function* () { yield 'e'; })()  // generator
);
console.log([...merged]); // ['a', 'b', 'c', 'd', 'e']

// Composes with iterator helpers (Chrome 122+)
const result = Iterator.concat(sourceA, sourceB)
  .filter(x => x > 0)
  .map(x => x * 2)
  .take(5)
  .toArray();

// Eager alternative for comparison (allocates intermediate array)
const eager = [...sourceA, ...sourceB]
  .filter(x => x > 0)
  .map(x => x * 2)
  .slice(0, 5);

references