-
Notifications
You must be signed in to change notification settings - Fork 0
Home
RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.
It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O.
It supports Java 5 or higher and JVM-based languages such as Groovy, Clojure, JRuby, Kotlin and Scala.
Observables fill the gap by being the ideal implementation of access to asynchronous sequences of multiple items | ||
---|---|---|
single items | multiple items | |
synchronous | T getData() |
Iterable<T> getData() |
asynchronous | Future<T> getData() |
Observable<T> getData() |
Java Futures are straightforward to use for a single level of asynchronous execution but they start to add non-trivial complexity when they’re nested.
It is difficult to use Futures to optimally compose conditional asynchronous execution flows (or impossible, since latencies of each request vary at runtime). This can be done, of course, but it quickly becomes complicated (and thus error-prone) or it prematurely blocks on Future.get()
, which eliminates the benefit of asynchronous execution.
RxJava Observables on the other hand are intended for composing flows and sequences of asynchronous data.
RxJava’s Observables support not just the emission of single scalar values (as Futures do), but also of sequences of values or even infinite streams. Observable
is a single abstraction that can be used for any of these use cases. An Observable has all of the flexibility and elegance associated with its mirror-image cousin the Iterable.
An Observable is the asynchronous/push "dual" to the synchronous/pull Iterable | ||
---|---|---|
event | Iterable (pull) | Observable (push) |
retrieve data | T next() |
onNext(T) |
discover error | throws Exception
|
onError(Exception) |
complete | returns | onCompleted() |
The RxJava implementation is not biased toward some particular source of concurrency or asynchronicity. Observables in RxJava can be implemented using thread-pools, event loops, non-blocking I/O, actors (such as from Akka), or whatever implementation suits your needs, your style, or your expertise. Client code treats all of its interactions with Observables as asynchronous, whether your underlying implementation is blocking or non-blocking and however you choose to implement it.
RxJava also tries to be very lightweight. It is implemented as a single JAR that is focused on just the Observable abstraction and related higher-order functions. You could implement a composable Future that is similarly unbiased, but Akka Futures for example come tied in with an Actor library and a lot of other stuff.)
How is this Observable implemented? |
---|
public Observable getData(); |
From the Observer's point of view, it doesn't matter! |
|
And importantly: with RxJava you can later change your mind, and radically change the underlying nature of your Observable implementation, without breaking the consumers of your Observable.
Callbacks solve the problem of premature blocking on Future.get()
by not allowing anything to block. They are naturally efficient because they execute when the response is ready.
But as with Futures, while callbacks are easy to use with a single level of asynchronous execution, with nested composition they become unwieldy.
RxJava is meant for a more polyglot environment than just Java/Scala, and it is being designed to respect the idioms of each JVM-based language. (This is something we’re still working on.)
RxJava provides a collection of operators with which you can filter, select, transform, combine, and compose Observables. This allows for efficient execution and composition.
You can think of the Observable class as a “push” equivalent to Iterable, which is a “pull.” With an Iterable, the consumer pulls values from the producer and the thread blocks until those values arrive. By contrast, with an Observable the producer pushes values to the consumer whenever values are available. This approach is more flexible, because values can arrive synchronously or asynchronously.
Example code showing how similar high-order functions can be applied to an Iterable and an Observable | |
---|---|
Iterable | Observable |
|
|
The Observable type adds two missing semantics to the Gang of Four’s Observer pattern, to match those that are available in the Iterable type:
- the ability for the producer to signal to the consumer that there is no more data available (a foreach loop on an Iterable completes and returns normally in such a case; an Observable calls its observer's
onCompleted()
method) - the ability for the producer to signal to the consumer that an error has occurred (an Iterable throws an exception if an error takes place during iteration; an Observable calls its observer's
onError()
method)
With these additions, RxJava harmonizes the Iterable and Observable types. The only difference between them is the direction in which the data flows. This is very important because now any operation you can perform on an Iterable, you can also perform on an Observable.
We call this approach Functional Reactive Programming because it applies functions (lambdas/closures) in a reactive (asynchronous/push) manner to asynchronous sequences of data. (This is not meant to be an implementation of the similar but more restrictive “functional reactive programming” model used in languages like Fran.)
- LambdaJam Chicago 2013: Functional Reactive Programming in the Netflix API
- QCon London 2013 presentation: Functional Reactive Programming in the Netflix API and interview
- Functional Reactive in the Netflix API with RxJava
- RxJava: Reactive Extensions in Scala - video of Ben Christensen and Matt Jacobs presenting at SF Scala
- Functional Reactive Programming on Android With RxJava and Conquering concurrency - bringing the Reactive Extensions to the Android platform
- Top 7 Tips for RxJava on Android by Timo Tuominen
- FRP on Android by Yaroslav Heriatovych
- Optimizing the Netflix API
- Reactive Programming at Netflix
- rx.codeplex.com
- Rx Design Guidelines (PDF)
- Channel 9 MSDN videos on Reactive Extensions
- Your Mouse is a Database
- Beginner’s Guide to the Reactive Extensions
- Wikipedia: Reactive Programming
- Wikipedia: Functional Reactive Programming
- Tutorial: Functional Programming in Javascript and an accompanying lecture (video) by Jafar Husain.
- What is (functional) reactive programming?
- Rx Is now Open Source
- What is FRP? - Elm Language
- Rx Workshop: Observables vs. Events
- Rx Workshop: Unified Programming Model
- Introduction to Rx: Why Rx?
- The Reactive Manifesto
The following external libraries can work with RxJava:
- Hystrix latency and fault tolerance bulkheading library.
- Camel RX provides an easy way to reuse any of the Apache Camel components, protocols, transports and data formats with the RxJava API
-
rxjava-http-tail allows you to follow logs over HTTP, like
tail -f
- mod-rxjava - Extension for VertX that provides support for Reactive Extensions (RX) using the RxJava library
A Netflix Original Production
Tech Blog | Twitter @NetflixOSS | Twitter @RxJava | Jobs