2015-08-21 13 views
14

Ich benutze RxJava in und Android-Anwendung mit RxAndroid. Ich verwende mergeDelayError, um zwei Retro-Fit-Netzwerkaufrufe zu einer Observablen zu kombinieren, die ausgegebene Elemente verarbeiten wird, wenn eines ausgegeben wird, und den Fehler, wenn es eins hat. Dies funktioniert nicht und es wird nur die Aktion onError ausgelöst, wenn ein Fehler auftritt. Nun, um das zu testen, habe ich ein sehr einfaches Beispiel gewählt und immer noch wird die successAction nie aufgerufen, wenn ich einen onError-Aufruf habe. Siehe Beispiel unten.Rx Java mergeDelayError funktioniert nicht wie erwartet

Die Erfolgsaktion wird nur aufgerufen, wenn ich zwei Erfolgsobservablen verwende. Fehle ich etwas mit wie mergeDelayError funktionieren soll?

EDIT:

ich gefunden habe, dass, wenn ich die observeOn und subscribeOn alles entfernen wie erwartet funktioniert. Ich muss Threads angeben und dachte, dass das der Sinn von Rx ist. Irgendeine Idee, warum das Spezifizieren dieser Schedulers das Verhalten brechen würde?

+0

das doc sagt 'eine onError-Benachrichtigung von irgendeinem der Quellobservablen wird (...) das zusammengeführte Observable beenden. 'scheint klar aus dem Diagramm, dass jeder Fehler verzögert wird, bis alle anderen abgeschlossen sind, und Dann wird gefeuert und das Observable beendet, ohne dass es abgeschlossen ist. – njzk2

+0

so sollte man tatsächlich einmal die 'successAction', dann die Fehleraktion erhalten. (aber nicht die komplette) – njzk2

+0

Wie behaupten Sie, dass Erfolg nicht genannt wird? – njzk2

Antwort

3

Dies scheint immer noch wie ein Fehler im MergeDelayError-Operator, aber ich konnte es durch Duplizieren der ObserverOn und Subscribe für jede Observable arbeiten.

Observable.mergeDelayError(
      Observable.error(new RuntimeException()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribeOn(Schedulers.io()), 
      Observable.just("Hello") 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribeOn(Schedulers.io()) 
     ) 
     .finallyDo(completeAction) 
     .subscribe(successAction, errorAction); 
1

Ich glaube, Sie nicht für das Terminal Ereignis warten und der Haupt-Thread beendet, bevor die Ereignisse zu Ihrem Beobachter geliefert werden. Der folgende Test geht für mich mit RxJava 1.0.14:

@Test 
public void errorDelayed() { 
    TestSubscriber<Object> ts = TestSubscriber.create(); 
    Observable.mergeDelayError(
      Observable.error(new RuntimeException()), 
      Observable.just("Hello") 
     ) 
     .subscribeOn(Schedulers.io()).subscribe(ts); 

    ts.awaitTerminalEvent(); 

    ts.assertError(RuntimeException.class); 
    ts.assertValue("Hello"); 
} 
+0

Ich denke, wenn Sie auf 1.0.14 aktualisieren, wird das Snippet im ursprünglichen Problem funktionieren. –

8

Verwenden .observeOn (AndroidSchedulers.mainThread(), true) statt .observeOn (AndroidSchedulers.mainThread()

public final Observable<T> observeOn(Scheduler scheduler, boolean delayError) { 
     return observeOn(scheduler, delayError, RxRingBuffer.SIZE); 
    } 

Oben ist die Unterschrift von observeOn Funktion. Code Werke folgen.

Observable.mergeDelayError(
       Observable.error(new RuntimeException()), 
       Observable.just("Hello") 
     ) 
       .observeOn(AndroidSchedulers.mainThread(), true) 
       .subscribeOn(Schedulers.io()) 
       .subscribe(new Subscriber<String>() { 
        @Override 
        public void onCompleted() { 

        } 

        @Override 
        public void onError(Throwable e) { 

        } 

        @Override 
        public void onNext(String s) { 

        } 
       }); 

diesen Trick von C Got oncatDelayError thread: https://github.com/ReactiveX/RxJava/issues/3908#issuecomment-217999009

+1

Ich denke, das sollte die akzeptierte Antwort sein! Ich habe meinen Tag damit verbracht, dieses Problem zu beheben. Wie auch immer, es ist sehr verwirrend, dass Sie 2 mal angeben müssen, dass Sie den Fehler verzögern möchten! –

+0

Es funktioniert nicht für mich; "( –

Verwandte Themen