Every reactive system—whether RxJS in the browser, Reactor on the JVM, or RxSwift on iOS—derives from a single contract defined at reactivex.io: an Observable emits items to an Observer via three lifecycle methods. `onNext(item)` delivers values. `onError(throwable)` signals an unrecoverable failure and terminates the sequence. `onComplete()` signals a clean end. No item arrives after either terminal event. This is not a convention—it is a formal invariant the entire operator ecosystem depends on. The distinction between cold and hot Observables is the most consequential design decision a reactive engineer makes. Cold Observables begin emitting only when subscribed; each subscriber gets its own independent execution. An HTTP request wrapped as a cold Observable fires one request per subscriber—helpful for independent parallel fetches, catastrophic if you expected a shared result. Hot Observables emit regardless of subscribers; a mouse event stream, a WebSocket feed, or a Kafka partition offset sequence is hot by nature. ConnectableObservable bridges the gap: it is a hot Observable that only begins emitting after an explicit `connect()` call, enabling multiple subscribers to synchronize on the same upstream activation. Reactor's `Flux` (0 to N items) and `Mono` (0 or 1 item) implement this contract at the JVM level while integrating directly with the Reactive Streams specification, which defines `Publisher`, `Subscriber`, `Subscription`, and `Processor` interfaces. Java 9's `Flow` API maps semantically one-to-one with Reactive Streams, with a default buffer of 256 items. RxJava 2 and later prohibit null emissions entirely—a deliberate spec compliance choice that eliminates a class of `NullPointerException` crashes. Kotlin Flow is cold by definition; every `collect` invocation starts a fresh emission. `SharedFlow` and `StateFlow` are Kotlin's hot equivalents, replacing many `BehaviorSubject` and `PublishSubject` usages from the RxJava era. In practice, Kotlin coroutines with Flow have become the default for new Android projects, displacing RxJava for most greenfield work. The Observable contract is rank 1 not because it is the most sophisticated pattern, but because every other pattern in this list is built on top of it. Remove it and there is nothing left to compose.
Comments on "Observer & Observable Streams"
Create a free account or sign in to join the discussion.
Sign in to join the conversation