2017-05-16 2 views
0

Angenommen, ich den folgenden Code haben:Warum retryWhen() nicht halten?

Observable.error(new Throwable()). 
    retryWhen(notificationHandler -> Observable.never()). 
    subscribe(x -> {}, t -> log("error"),() -> log("completed")); 

erwarte ich, dass sie die Ausführung halten wird, weil retryWhen wird nie oder getan resubscribe.

Aber wenn ich es ausführe, stoppt die Anwendung, auch nicht Fehler oder konkurriert.

Warum hält es nicht immer?

P.S. Ich hatte die Idee, diese Ausführung zu unterbrechen, weil alles auf einem einzigen Thread läuft. Und versuchte Bewegung retryWhen() -Prozedur zu einem anderen Thread:

Observable.error(new Throwable()). 
     retryWhen(notificationHandler -> Observable.create(subscriber -> { 
      log("never"); 
     }).observeOn(Schedulers.newThread())). 
     subscribe(x -> {}, t -> log("err"),() -> log("completed")); 

Aber es does'not Hilfe - noch druckt 'nie' und stoppt.

+0

Könnten Sie bitte erklären, was Sie tun möchten? Welche Art von Verhalten möchten Sie implementieren? Welche Art von Bewerbung hast du? Ist es eine Android-Anwendung? –

Antwort

0

haben Sie einen Blick auf die explaniation von Dan auf folgenden Link: http://blog.danlew.net/2016/01/25/rxjavas-repeatwhen-and-retrywhen-explained/

Es

erste im letzten Teil sieht sagen lassen. Die zurückgegebenen Observable-Werte bestimmen, ob eine erneute Registrierung stattfindet oder nicht. Wenn es onCompleted oder onError ausgibt, wird es nicht erneut abonniert. Aber wenn es onNext ausstrahlt dann tut es (egal was eigentlich im onNext ist).

retryWenn subskribiert Observable.never(), was wiederum keinen Wert zur Verfügung stellt. Daher steht die Pipeline an einem Verkaufsstand und Ihre Bewerbung wird nicht fortgesetzt. entweder Sie werfen e onError/onComplete oder nur einen Wert:

Ermöglicht bei diesem Test einen Blick. Es wird angezeigt, dass kein Wert ausgegeben wird und dass er nicht erneut abonniert wird.

@Test 
void name2() throws Exception { 
    boolean await = Observable.error(new Throwable()) 
      .doOnEach(objectNotification -> System.out.println("x")) 
      .retryWhen(notificationHandler -> Observable.never()) 
      .map(o -> -42) 
      .doOnNext(System.out::println) 
      .test() 
      .await(100, TimeUnit.MILLISECONDS); 

    assertThat(await).isFalse(); 
} 

erwarte ich, dass sie die Ausführung halten wird, weil retryWhen wird nie oder getan resubscribe. Aber wenn ich es ausführe, stoppt die Anwendung, auch wenn sie keinen Fehler anzeigt oder konkurriert.

Die Anwendung zeigt nichts an, weil subscribe onComplete/onError nie erreicht wird, wegen Observable.never().

0

Zunächst denke ich, Sie sind mit Observable.never und Observable.empty verwechselt. Wenn Sie Observable.never verwenden, wird es weder erneut ausgeführt noch abgeschlossen (Der Fehler wurde von notificationHandler verbraucht).

Zweitens, wenn Sie retryWhen verwenden, sollten Sie auf der gegebenen notificationHandler abonnieren. Oder es wird sofort erneut versucht, wenn subscribe (Der Parameter Func1<> notificationHandler wird aufgerufen werden, wenn Sie abonnieren, und versuchen Sie es erneut, wenn die Observable-Ausgabe zurückgeben).