One call every 100 ms
Requirement
Send five pings to a rate-limited endpoint, each starting at least
100 ms after the previous one. Record every call's
start on a monotonic Stopwatch, print the five responses,
and print spaced: true only if all gaps respected the
limit. Both versions must print the lines shown under
Expected output.
Expected output
pong #1 pong #2 pong #3 pong #4 pong #5 spaced: true
Side by side
RxDart
FxDart
Why they differ
Pacing is about time, so you might expect the stream to win — and
RxDart does have the word for it: interval holds each
event back 100 ms before it reaches the ping, and backpressure
keeps the whole thing sequential. One operator, requirement met.
But a pull pipeline is sequential by default, and that turns pacing
into something almost embarrassingly simple: put the delay
inside the mapper. Each pull waits 100 ms, then calls —
the next pull cannot begin until this one finishes, so the spacing is
structural, no operator needed. The Stopwatch check prints
spaced: true on both sides. Call it a tie with a caveat
each way: RxDart names the concept explicitly, which reads better in
a pipeline full of other time operators; FxDart gets it as a
one-line consequence of demand, but only because this task wants
strictly serial calls — for spacing events that arrive on their own
schedule (a real event stream), reach for the stream side of the
bridge (fxStream) and RxDart's time vocabulary.
Benchmark
No benchmark for this example. This operator is defined by elapsed time, not by work done: both sides wait out the same windows, so a bar would be measuring Dart's timers rather than either library. Shrinking the windows does not help either — how many values a burst produces would then depend on how fast the machine is, and the two sides could no longer be checked against an identical result. The examples built on timing operators are left unmeasured for that reason; the ones whose delays merely stand in for I/O are benchmarked with those delays set to zero.