2014-01-21 13 views
31

Unter dem subjects Paket haben Sie Klassen wie PublishSubject und BehaviorSubject, die ich als einige brauchbare Probe Observables beschrieben werden kann.Wie können PublishSubject und BehaviorSubject abgemeldet werden?

Wie können diese Themen abbestellt werden? Es gibt keine unsubscribe Methode und Aufruf onCompleted endet die Observable insgesamt richtig?

Antwort

60

Ein Betreff ist ein Observable und ein Observer gleichzeitig, es kann von normalen Observablen abgemeldet werden. Was das Thema besonders macht, ist, dass es eine Art Brücke zwischen Observablen und Beobachtern ist. Es kann die beobachteten Objekte passieren, indem es sie erneut ausgibt, und es kann auch neue Objekte ausgeben. Themen sind Observable wie Versprechen zu Futures.

hier ist eine kurze Beschreibung der Familie Themen:

AsyncSubject: gibt die zuletzt emittierten Artikel und all nachfolgenden Elemente: nur den letzten Wert der Quelle

BehaviorSubject beobachtbare

emittiert der Quelle Observable, wenn ein Beobachter es abonnieren

PublishSubject: emittiert alle folgenden Elemente der Quelle Observable zum Zeitpunkt des Abonnements

ReplaySubject: Gibt alle Elemente der Quelle Observable, unabhängig davon, wann der Abonnent abonniert.

die official doc kommt mit einigen netten Marmor Diagramme, die es leichter zu verstehen

+2

Ist BehaviorSubject im Wesentlichen das gleiche wie ReplaySubject (1)? –

+1

@DzmitryLazerka: BehaviorSubject hat immer einen Anfangswert. Wenn Sie nach BehaviorSubject ohne Anfangswert suchen, verwenden Sie ReplaySubject (1). – gregschlom

+0

Große Antwort obwohl leichte Korrektur - ReplaySubject kann auch einen Puffer in create() angeben, der die Anzahl der Elemente angibt, die im Abonnement ausgegeben werden – jklp

21

Themen sind im Wesentlichen beide Observables und Beobachter.

Ein Observable ist im Wesentlichen eine Sache, die eine Funktion hat, die einen Beobachter nimmt und ein Abonnement zurückgibt. So zum Beispiel, da einfach zu beobachten:

Observable<Integer> observable = Observable.create(new Observable.OnSubscribeFunc<Integer>() { 
     @Override 
     public Subscription onSubscribe(Observer<? super Integer> observer) { 
      observer.onNext(3); 
      observer.onNext(2); 
      observer.onNext(1); 
      observer.onCompleted(); 

      return Subscriptions.empty(); 
     } 
    }); 

Und hier möchten wir es, abonnieren Sie für jede ganze Zahl eine Zeile drucken:

Subscription sub = observable.subscribe(new Action1<Integer>() { 
     @Override 
     public void call(Integer integer) { 
      System.out.println(integer); 
     } 
    }); 

Sie auf der oben durch den Aufruf sub.unsubscribe() austragen würde.

ist hier ein PublishSubject, die in etwa die gleiche Sache tut:

PublishSubject<Integer> publishSubject = PublishSubject.create(); 
    Subscription subscription = publishSubject.subscribe(new Action1<Integer>() { 
     @Override 
     public void call(Integer integer) { 
      System.out.println(integer); 
     } 
    }); 

    publishSubject.onNext(3); 
    publishSubject.onNext(2); 
    publishSubject.onNext(1); 

Sie von ihm die gleiche Art und Weise austragen würde, durch subscription.unsubscribe() aufrufen.

+0

Könnten Sie bitte beschreiben, wie wir Abonnenten onNext parallel behandeln lassen? Wenn es mehrere Abonnenten nicht nur einen geben würde, wie würden wir sie parallel ausführen – vach

+2

@Vach - wie oben beschrieben Code könnten Sie Abonnenten onNext parallel behandeln, indem Sie so etwas tun: 'Abonnement subscription1 = publishSubject.observeOn (Schedulers .newThread()) abonnieren. (...); ' und ' Abonnement subscription2 = publishSubject.observeOn (Schedulers.newThread()) zeichnen (...);. ' –

+0

ich immer gefragt, wie dies zu tun und ich habe es bis jetzt nicht verstanden, thx @ praveer09 :) –

4

Alle Subjects erweitern Observable macht, die Sie mit einer der mehreren subscribe(...) Methoden abonnieren können. Aufruf an irgendeine der subscribe(...) Methoden gibt eine Subscription zurück.

Subscription subscription = anySubject.subscribe(...); 

verwenden subscription der Instanz unsubscribe() Methode, wenn Sie aus dem Betreff der Ereignisse hören beenden möchten.

subscription.unsubscribe();