attach
Pair each value with what you derive from it — the input stays beside its result.
Lecture
map replaces each value with its
result — and the moment you need the input again downstream
(to fall back, to label, to log), you find yourself hand-building
records: .map((x) async => (x, await f(x))).
attach(f) is that idiom as an operator: it yields
(value, f(value)) pairs, lazily.
It earns its keep in async chains. Look up a price per item and the
pair keeps the item next to the (maybe missing) price, so the fallback
r.$2 ?? r.$1.listPrice and the "which SKU was
that?" label are both still in reach. The async form is built on
mapAsync, so it is parallel-safe — put
concurrent(n) after it and
n lookups run at once.
Dart-native addition (no FxTS counterpart). When you only need the
derived value, keep using map; when you need it keyed by
the input as a lookup table, that is
indexBy.
Demo 1 · The input survives the map
Demo 2 · Async lookups with fallback
Try it yourself
Exercise: keep each query beside its search results.
map — when the input can go ·
zip — pairing two separate sequences ·
concurrent — bound the async fan-out after attaching