Esta página ainda não foi traduzida, por isso é exibida em inglês. Ajude a traduzir

share & LiveValue.from

One run of a chain, many listeners — and the version that remembers its latest value for whoever arrives late.

FxEvents<T> FxEvents<T>.share({bool reset = true}) // chain (events); resubscribes after last-cancel unless complete LiveValue<T>.from(Stream<T> source) // hot, unseeded LiveValue<T>.seededFrom(T seed, Stream<T> source) // hot, seeded

Lecture

Every operator in this section builds its own StreamController, so the chain it returns is single-subscription: listen to it twice and the second listener gets a StateError. That default is deliberate — it keeps the chain cold, so nothing runs until someone consumes it, and it keeps per-listener state honest. But it means two widgets cannot watch the same debounced, throttled, switch-mapped feed without building it twice.

share() fixes that. It connects on the first listener and broadcasts to every listener from there, so the work upstream happens once no matter how many are watching. A debounce timer, a socket, an expensive map — one of each, not one per subscriber.

share({reset: true}) — the default — now matches Rx's ref-count reset. When the last listener leaves before the source has completed, the upstream subscription is cancelled and the next listener starts a fresh subscribe. After the source completes, a later listener is still handed a closed stream. share(reset: false) is the 0.8.7 behaviour: the last cancel closes forever. A resubscribe needs a source that allows a second listen — Stream.fromIterable, Stream.multi, FxEvents.defer, a broadcast — a spent single-subscription StreamController still cannot be re-listened. Attach every listener before the first event if the source is one-shot, or keep one alive.

share() also does not remember: a listener that arrives after an event has passed has simply missed it. For a window of history, shareReplay is the next page. When latecomers need the current state — which is most UI — LiveValue is the answer, and LiveValue.from(source) / LiveValue.seededFrom(seed, source) build one directly from a stream. Those are hot: the subscription opens immediately, so values arriving before anyone listens still update value, and close() cancels the source. They are named constructors rather than an optional seed so that a nullable T can still be seeded with null. fxdart events layer, after Rx's share and shareValue.

Demo 1 · Why one listener is the default

Demo 2 · One run, two listeners

Try it yourself

Exercise: a LiveValue fed straight from a stream.

Related: shareReplay — multicast that remembers a buffer of history · LiveValue — the sharing that remembers: late subscribers get the current value first · tee — the pull-side answer to two readers over one pass, with no buffer · fork — two independent pull cursors over one source, at the cost of a buffer