Each call feeds the next
Requirement
Four API steps run strictly one after another — login, profile, orders, invoice — and each request is built from the previous response (the session id feeds the profile call, the user id feeds the orders call, …). Print each step with its response. The fake API table is in the code; both versions must print the lines shown under Expected output.
Expected output
login -> session-9 profile -> user-42 orders -> order-7 invoice -> pdf-3
Side by side
RxDart
FxDart
Why they differ
Neither model has to fight for sequentiality here. RxDart's
asyncMap pauses the source while each future
runs, so the calls are serial by construction; a pull pipeline only
ever asks for the next value after the previous one resolved, so it
is serial by default. The interesting difference is where the
dependency — the token each response hands the next request —
lives.
The RxDart side threads it through a mutable variable the mapper
closes over: idiomatic, compact, and slightly outside the pipeline —
the data flow between steps is invisible to the operator chain. The
FxDart side threads it through scan's accumulator, so
the previous response is an explicit input of the next step; the cost
is that scan emits its seed, which the printout has to
skip. One hidden variable versus one skipped seed line — a genuine
tie, decided by whether you prefer state captured in a closure or
state visible in the fold.
Benchmark
Async case: the headline scale is N = 10,000, not 1,000,000. Every element costs an event-loop turn on both sides, so a million real awaits would measure Dart's event loop for minutes — not the pipeline. Delays are zero-length and the example's concurrency limit is kept; what the bars compare is the pipeline machinery.
N = 100
Time Tie
Peak memory Tie
N = 10,000
Time Tie
Peak memory Tie
Bars are medians of repeated timed iterations in fresh processes per side (small N is batched for timer resolution). Sides within 5% of each other — or within 0.6 ms, a difference no person can perceive — count as a tie; close relative races are re-measured up to 5 runs. In an app, anything under a few milliseconds is invisible to the user regardless of which bar is shorter. Memory is peak process RSS. The Dart VM and the dataset are identical on both sides, so the difference between the two bars is what the pipeline itself holds onto.