fork
Branches one buffered iteration of a source into independent, replayable readers.
Lecture
Iterating the same Dart Iterable object twice normally runs
its source twice — a sync* generator restarts from scratch
every time you ask for a fresh .iterator. That's wasteful
(or outright wrong) when producing a value is expensive: a network
fetch, a slow computation, a stream you can only read once.
fork fixes this: every call to fork(iterable)
with the same iterable object returns an
independent cursor over one shared, lazily-growing buffer. The
underlying source is walked exactly once, no matter how many forks read
from it or in what order.
The sharing is keyed by the identity of the iterable you
pass in (via an internal Expando), so you must fork the
same object — not two separately-constructed iterables that
happen to look alike. Each fork can be consumed at its own pace: reading
ahead on one fork pulls new values from the source and appends them to
the shared buffer; a fork that's behind just replays values already in
the buffer, at no extra cost. forkAsync works the same way
for FxAsyncIterable, and additionally lets concurrent
downstream demand from multiple forks pull the shared async source in
parallel.
Demo 1 · One source, two branches, proven with a counter
source() increments calls every time it
produces a value. Both evens and doubled fork
the exact same shared object — if the source ran twice,
calls would end up at 10, not 5:
Demo 2 · Forks at different paces share one buffer
Branch a races ahead and pulls two fresh values; when
branch b asks for its first two, it simply replays what
a already buffered — no new calls to source()
until b needs a third value neither fork has seen yet:
Try it yourself
Exercise: right now readings is iterated twice with no
fork, so sensor() runs twice and
reads ends up at 6. Fork readings for each
consumer so the sensor is only read once (reads should be
3).
peek — observe without branching ·
concurrent — parallel evaluation within one branch ·
memoize — cache a single value instead of a whole sequence