2015-11-18 9 views
19

Po utworzeniu obserwowalnego od zera i po wystąpieniu błędu obserwatora, zakończona część subskrypcji nigdy nie zostanie wywołana.Obserwowane obiekty rxjs nie kończą się po wystąpieniu błędu.

var observer = Rx.Observable.create(function(observer){ 
    observer.onError(new Error('no!')); 
    observer.onCompleted(); 
}) 

observer.subscribe(
    function(x) { console.log('succeeded with ' + x) }, 
    function(x) { console.log('errored with ' + x) }, 
    function() { console.log('completed') } 
) 

Wyjście jest:

errored with Error: no! 

będę oczekiwać, że będzie:

errored with Error: no! 
completed 

Gdybym zmienić kod powołać onNext zamiast onError, obserwowalny prawidłowo ukończył:

var observer = Rx.Observable.create(function(observer){ 
    observer.onNext('Hi!'); 
    observer.onCompleted(); 
}) 

observer.subscribe(
    function(x) { console.log('succeeded with ' + x) }, 
    function(x) { console.log('errored with ' + x) }, 
    function() { console.log('completed') } 
) 

Dostaję oczekiwana moc wyjściowa:

succeeded with Hi! 
completed 

Dlaczego nie jest kompletny, gdy wystąpił błąd?

Odpowiedz

21

To dlatego, że błąd oznacza zakończenie, więc wywołanie zwrotne powiązane z onCompleted nigdy nie zostanie wywołane. można przejrzeć tutaj Rxjs umowę obserwabli (http://reactivex.io/documentation/contract.html):

zauważalny może dokonać zero lub powiadomień więcej OnNext, z których każda reprezentuje jedno emitowanego element, a może następnie postępuj tych powiadomień emisji albo przez OnCompleted lub onError powiadomienie, ale nie obie. Na wydanie OnCompleted lub onError zgłoszenie, nie może następnie wydać dalsze notifications.`

Dla zarządzania błędów, można rzucić okiem na: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/errors.md

+3

Dzięki! Widzę to wyjaśnienie: OnError wskazuje, że obserwowalne zostało zakończone z określonym błędem i że nie będzie emitować dalszych elementów –

6

Choć miałem to samo pytanie, ja wpadł na to github issue.

Najprawdopodobniej należy użyć obiektu finally z obiektu Observable w tym przypadku.

Cytując Aleksandr-Leotech z tego wątku:

Kompletna i wreszcie są zupełnie różne rzeczy. Kompletny oznacza, że ​​ obserwowalna para została pomyślnie zakończona. Ponieważ możesz mieć wiele udanych połączeń. Ostatecznie oznacza to, że para zakończyła się pomyślnie, czy też nie.

Nie jest to oczywiste w przypadku żądań HTTP, ale wyobraź sobie dwa dodatkowe scenariusze: .

  1. Wydarzenia dotyczące myszy. Otrzymasz nieskończoną parę sukcesów oddzwonienia, ale nigdy nie otrzymasz w końcu ani końca, ponieważ zdarzenia użytkownika nigdy się nie zatrzymają (chyba że uruchomisz wyjątek z kodem błędu , wtedy dostaniesz błąd i na końcu).

  2. Praca z gniazdami internetowymi. Otrzymasz wiele potwierdzeń powodzenia, ale w pewnym momencie twoja komunikacja z zapleczem zatrzyma się i otrzymasz zarówno kompletne, jak i ostateczne, chyba że masz jakieś błędy, które wywołają błąd i na końcu.

Możliwe, że otrzymujesz wielokrotne lub żadne wywołanie sukcesu, zero lub jedno wywołanie błędu, zero lub jeden kompletny i zero lub jeden w końcu.

Powiązane problemy