Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reactive Extensions for JVM

Blaž Šolar
December 21, 2015

Reactive Extensions for JVM

Blaž Šolar

December 21, 2015
Tweet

More Decks by Blaž Šolar

Other Decks in Programming

Transcript

  1. “ReactiveX is a combination of the best ideas from the

    Observer pattern, the Iterator pattern, and functional programming” - ReactiveX
  2. Limited method signature public Data getData(); What if the implementation

    needs to change from synchronous to asynchronous How should the client execute this method without blocking? Spawn a thread?
  3. Let’s do it async public void getData(Callback<T> c); public Future<T>

    getData(); public Future<List<Future<T>>> getData();
  4. Observable push onNext(T) onError(Exception) onCompleted() Iterable pull T next() throws

    Exception returns getDataFromLocalMemory() .skip(10) .take(5) .map({ s -> s + "_transformed" }) .forEach({ println "onNext => " + it }) getDataFromNetwork() .skip(10) .take(5) .map({ s -> s + "_transformed" }) .subscribe({ println "onNext => " + it })
  5. How to deal with data Single Multiple Sync T getData();

    Iterable<T> getData(); Async Future<T> getData(); Observable<T> getData();
  6. How to deal with data Single Multiple Sync T getData();

    Iterable<T> getData(); Async Future<T> getData(); Observable<T> getData(); String s = getData(); if(s.equals(x)) { // do something } else { // do something else }
  7. How to deal with data Single Multiple Sync T getData();

    Iterable<T> getData(); Async Future<T> getData(); Observable<T> getData(); Iterable<String> values = getData(); for(String s : values) { if(s.equals(x)) { // do sometinhg } else { // do something else } }
  8. How to deal with data Single Multiple Sync T getData();

    Iterable<T> getData(); Async Future<T> getData(); Observable<T> getData(); Future<String> s = getData(); if(s.get().equals(x)) { // do sometinhg } else { // do something else }
  9. How to deal with data Single Multiple Sync T getData();

    Iterable<T> getData(); Async Future<T> getData(); Observable<T> getData(); CompletableFuture<String> s = getData(); s.thenAply((v) -> { if(v.equals(x)) { // do something } else { // do something else } })
  10. How to deal with data Single Multiple Sync T getData();

    Iterable<T> getData(); Async Future<T> getData(); Observable<T> getData(); Future<String> s = getData(); s.map({ s -> if(s.equals(x)) { // do something } else { // do something else } })
  11. How to deal with data Observable<String> s = getData(); s.map({

    s -> if(s.equals(x)) { // do something } else { // do something else } }) Single Multiple Sync T getData(); Iterable<T> getData(); Async Future<T> getData(); Observable<T> getData();
  12. Synchronous Observable with single value Observable.create({ observer -> try {

    Location location = /** get last location */ observer.onNext(location); observer.onCompleted(); } catch(Exception e) { observer.onError(e); } })
  13. Asynchronous Observable with single value Observable.create({ observer -> executor.execute(new Runnable()

    { def void run() { try { Location location = /** get location */ observer.onNext(location); observer.onCompleted(); } catch(Exception e) { observer.onError(e); } } }) })
  14. Synchronous Observable with multiple values Observable.create({ observer -> try {

    for(l in locations) { observer.onNext(l); } observer.onCompleted(); } catch(Exception e) { observer.onError(e); } })
  15. Asynchronous Observable with multiple values Observable.create({ observer -> executor.execute(new Runnable()

    { def void run() { try { for(l in location) { location = /** resolve location */ observer.onNext(location); } observer.onCompleted(); } catch(Exception e) { observer.onError(e); } } }) })
  16. Composable functions Transform: map, flatMap, reduce, scan, ... Filter: take,

    skip, sample, takeWhile, filter, .... Combine: count, merge, zip, combineLatest, multicast, publish, cache Concurrency: observeOn, subscribeOn Error Handling: onErrorReturn, onErrorResume, ...
  17. Synchronous Observable with single value Observable.create({ observer -> try {

    Location location = /** get last location */ observer.onNext(location); observer.onCompleted(); } catch(Exception e) { observer.onError(e); } })
  18. Combining via Merge Observable<Data> a = getDataA(); Observable<Data> b =

    getDataB(); Observable.merge(a, b) .subscribe( { element -> println "data: " + element})
  19. Combining via Merge Observable<Data> a = getDataA(); Observable<String> b =

    getDataB(); Observable.zip(a, b, {x, y, -> [x, y]}) .subscribe( { pair -> println "a: " + pair[0] +"b: " + pair[1]})
  20. Error handling Observable<Data> a = getDataA(); Observable<String> b = getDataB();

    Observable.zip(a, b, {x, y, -> [x, y]}) .subscribe( { pair -> println "a: " + pair[0] +"b: " + pair[1]}, { exception -> println "Exception " + exception.getMessage})
  21. Error handling Observable<Data> a = getDataA(); Observable<String> b = getDataB()

    .onErrorResumeNext(getFallbackForB()); Observable.zip(a, b, {x, y, -> [x, y]}) .subscribe( { pair -> println "a: " + pair[0] +"b: " + pair[1]}, { exception -> println "Exception " + exception.getMessage})