2017-08-03 30 views
5

W skrócie: Jak kontynuować odsłuchiwanie po wystąpieniu błędu w strumieniu bez umieszczania .catch przed każdym .subscribe?Dlaczego Rxjs rezygnuje z subskrypcji po błędzie?

Jeśli potrzebujesz więcej szczegółów są tutaj:

Załóżmy mam przedmiotem bieżącego użytkownika lub null. Dostaję dane z API czasami i wysyłam do Tematu. To odpowiednio aktualizuje widok. Ale w pewnym momencie błąd wystąpił na moim serwerze i chcę, aby moja aplikacja kontynuowała pracę jak poprzednio, ale zawiadamia niektóre miejsca o błędzie i KEEP słucha mojego Tematu.

Początkowo myślałem, że jeśli po prostu wykonam userSubject.error(...), wywoła ona tylko wywołania zwrotne .catch i error dla subskrybentów i pominie wszystkie procedury obsługi i łańcuchy sukcesów. A jeśli po tym, jak zadzwonię pod numer userSubject.next(...), wszystkie moje sieci i subskrybenci będą działać tak jak poprzednio

ALE niestety tak nie jest. Po pierwszym nieprzechwyceniu .error anuluje subskrypcję ze strumienia i nie działa już.

Moje pytanie: dlaczego? Co należy zrobić, jeśli chcę obsłużyć normalnie wartość null, ale w niektórych miejscach obsługuję również błędy?

Oto link do kodu źródłowego RxJs gdzie unsubscribes Abonencka błędu https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts#L140

Odpowiedz

5

Rx obserwable follow the grammarnext*(error|complete)?, co oznacza, że ​​mogą one produkować nic po error lub complete notyfikacja została dostarczona.

wyjaśnienie, dlaczego to sprawy można znaleźć od Rx design guidelines:

Pojedynczy komunikat wskazujący, że obserwowalne sekwencja zakończy zapewnia, że ​​konsumenci obserwowalnym sekwencji może deterministycznie ustalić, że jest to bezpieczne wykonywanie operacji czyszczenia .

Pojedyncza awaria dodatkowo zapewnia zachowanie semantyki przerywania dla operatorów pracujących na wielu obserwowalnych sekwencjach.

W skrócie, jeśli chcesz, aby obserwatorzy zachować słuchania pacjenta po wystąpieniu błędu serwera, nie dostarczają tego błędu na ten temat, ale raczej poradzić w inny sposób (na przykład użyć catch, retry lub dostarczyć błąd do dedykowanego tematu).

+0

rozumiane dzięki! – mgrinko

3

Każda obserwowalna emituje zero lub więcej powiadomień next i jednąlub complete, ale nigdy obie.

Z tego powodu podmioty mają stan wewnętrzny.

To zależy od tego, jak zbudujesz swój łańcuch. Na przykład możesz użyć numeru retry(), aby ponownie przesłać subskrypcję do źródła Observable on error.

Albo kiedy przechodzą wartości do tematu można wysłać tylko next powiadomień i ignorować pozostałe dwa:

.subscribe(v => subject.next(v)); 

Albo jeśli chcesz wyrzucić błąd, gdy użytkownik jest null można użyć dowolnego operatora, który przechwytuje wyjątki i wysyła je jako powiadomienia o błędach. Na przykład:

.map(v => { 
    if (v === null) { 
     throw new Error("It's broken"); 
    } 
    return v; 
}) 

W każdym razie trudno podać dokładniejsze porady bez kodu.

+0

dziękuję, dowiesz się, co to jest 'retry()' – mgrinko

Powiązane problemy