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

RxJava: a Java implementation of Reactive Extentions

RxJava: a Java implementation of Reactive Extentions

A short introduction to Reactive Extentions for the JVM

Alessandro Calzavara

September 29, 2015
Tweet

More Decks by Alessandro Calzavara

Other Decks in Programming

Transcript

  1. "It extends the observer pattern to support sequences of data

    and/or 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." @ ReactiveX.io “
  2. OBSERVER PATTERN THE BASICS OF Observer: • handle notifications Subject:

    • register/unregister observers • notify observers
  3. SIMPLE API EVERYTHING BEGINS WITH A public Data getData(); Owner

    of API should retain control of concurrency behaviour. User should simply not care how it work behind.
  4. CHANGE API CHANGE INTERACTION BY single items multiple items synch

    T getData() Iterable<T> getData() asynch Future<T> getData() Observable<T> getData()
  5. ITERABLE and OBSERVABLE DUALITY BETWEEN Iterable Observable pull push T

    next() onNext(T) throws Exception onError(Exception) returns onCompleted()
  6. T getData() SYNC SINGLE ITEM String s = getData(args); if

    (s.equals(x)) { // do something } else { // do something else }
  7. Iterable<T> getData() SYNC MULTIPLE ITEMS Iterable<String> values = getData(args); for

    (String s : values) { if (s.equals(x)) { // do something } else { // do something else } }
  8. Future<T> getData() ASYNC SINGLE ITEM Future<String> s = getData(args); if

    (s.get().equals(x)) { // do something } else { // do something else }
  9. FUTURES REMOVE BLOCKING WITH Future<String> d = getData(args); Futures.addCallback(d, new

    FutureCallback<String> { public void onSuccess(String s) { if (s.equals(x)) { // do something } else { // do something else } } }, executor);
  10. COMPOSABLE FUTURE REMOVE BLOCKING WITH Future<String> d = getData(args); d.map({

    s -> if (s.equals(x)) { // do something } else { // do something else } }); Only Java 8+ or Scala
  11. Observable<T> getData() ASYNC MULTIPLE ITEMS Observable<String> d = getData(args); d.map({

    s -> if (s.equals(x)) { // do something } else { // do something else } });
  12. OBSERVABLE API MORE FLEXIBLE One interface to rule them all.

    Client code treats all interactions with the API as ASYNCHRONOUS. The API implementation chooses whether something is BLOCKING or NON- BLOCKING and WHAT resources it uses.
  13. Observable.create(new OnSubscribe<String>() { @Override public void call(Subscriber<String> subscriber) { try

    { subscriber.onNext("Hello"); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } } })
  14. Observable<Image> getTopImages() { return Observable.create(new OnSubscribe<Image>() { @Override public void

    call(Subscriber<Image> subscriber) { try { for (id in imageIds) { Image i = …do network call… subscriber.onNext(i); } subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } } })
  15. getTopImages().subscribe(new Observer<Image>() { void onNext(Image image) { println("Image: " +

    image.getImageId()); } void onError(Exception e) { println("Error"); e.printStackTrace(); } void onCompleted() { println("Completed"); } });
  16. Transform: map, flatmap, reduce, scan Filter: take, skip, sample, takeWhile,

    filter Combine: concat, merge, zip, combineLatest,
 multicast, publish, cache, refCount Concurrency: observeOn, subscribeOn Error handling: onErrorReturn, onErrorResume OPERATORS COMPOSABLE FUNCTIONS AKA
  17. this._episodeRepository.getEpisodeWithSegments(episodeId) .map(new Func1<Episode, Episode>() { @Override public Episode call(Episode episode)

    { // Check if EPISODE segment is available… } }) .flatMap(new Func1<Episode, Observable<Episode>>() { @Override public Observable<Episode> call(final Episode episode) { // Write episode to database… } }) .subscribeOn(RxSchedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<Episode>() { // Add download to queue or notify error… });
  18. MAP CHECK IF AUDIO SEGMENT IS AVAILABLE .map(new Func1<Episode, Episode>()

    { @Override public Episode call(Episode episode) { // Check if EPISODE segment is available String downloadUrl = null; for (AudioSegment segment : episode.getSegments()) { if (segment.getType() == AudioSegment.Type.EPISODE && segment.getHttpUrl() != null) { downloadUrl = segment.getHttpUrl(); break; } }
  19. MAP CHECK IF AUDIO SEGMENT IS AVAILABLE episode.getSegments()) { if

    (segment.getType() == AudioSegment.Type.EPISODE && segment.getHttpUrl() != null) { downloadUrl = segment.getHttpUrl(); break; } } if (downloadUrl == null) { throw new IllegalArgumentException(…); } // Update episode property episode.setOfflineUrl(downloadUrl); episode.setOfflineFilepath(_destinationFileForEpisode( episode.getEpisodeId()).getAbsolutePath()); episode.setOfflineAt(createdAt); episode.setOfflineStatus(Episode.OfflineStatus.WAITING); return episode; } })
  20. FLATMAP WRITE EPISODE TO DATABASE WITH .flatMap(new Func1<Episode, Observable<Episode>>() {

    @Override public Observable<Episode> call(final Episode episode) { // Write episode to database return _offlineRepository .addOfflineEpisodeDatabase(ep) .map(new Func1<Boolean, Episode>() { @Override public Episode call(Boolean added) { return ep; } }); }})
  21. SUBSCRIBE HANDLE ERROR OR SUCCESS ON .subscribe(new Subscriber<Episode>() { @Override

    public void onError(Throwable e) { // Notify failure … } @Override public void onNext(Episode episode) { // Notify success and add to download queue … } });
  22. Interactions with the API are ASYNCHRONOUS and DECLARATIVE API implementation

    controls CONCURRENCY BEHAVIOUR The only "rule" is: DON'T MUTATE STATE OUTSIDE OF FUNCTION LESSONS LEARNED TO SUM UP
  23. ReactiveX: http://reactivex.io What does it means to be Reactive? https://www.youtube.com/watch?

    v=sTSQlYX5DU0 RxJava @ Github: https://github.com/ReactiveX/RxJava Observer Pattern: https://en.wikipedia.org/wiki/ Observer_pattern Marbles diagrams: http://rxmarbles.com/