2016-07-06 15 views
12

Używam rury asynchronicznej Angular2 do strumieniowania wartości do DOM. Oto prawdziwy prosty przykład:Obsługa błędów za pomocą rury asynchronicznej Angular2

const stream = Observable.interval(1000) 
    .take(5) 
    .map(n => { if (n === 3) throw "ERROR"; return n; }); 

<div *ngFor="for num of stream | async"> 
    {{num}} 
</div> 

<div id="error"></div> 

Co chciałbym zrobić, to mieć sekwencję 1-5 wyświetlanej, ale na przedmiocie błędu (3), jakoś zapełnić #error div z komunikatem o błędzie.

Wydaje się, że wymaga to dwóch rzeczy: po pierwsze umiejętność rurek asynchronicznych Angular do zrobienia czegoś inteligentnego z błędami, którego nie widzę. Patrząc na kod źródłowy, najwyraźniej generuje wyjątek JS, który nie wydaje się zbyt przyjazny.

Druga to możliwość ponownego uruchomienia lub kontynuowania sekwencji po wystąpieniu błędu. Przeczytałem o catch i onErrorResumeNext i tak dalej, ale wszystkie one obejmują inną sekwencję, która zostanie przełączona na błąd. To bardzo komplikuje logikę generowania strumienia, na którym chciałbym umieścić serię liczb (w tym prostym przykładzie). Mam wrażenie, że po wystąpieniu błędu gra się kończy, a obserwowalna jest zakończona i może zostać "ponownie uruchomiona" z innym obserwowalnym. Wciąż uczę się obserwowalnych; czy tak rzeczywiście jest?

Więc moje pytanie jest dwojaki:

  1. Czy rura asynchroniczny Angular2 za coś inteligentnego z błędami?
  2. Czy obserwowalne mają prosty sposób kontynuacji po wystąpieniu błędu?

Odpowiedz

9

Tak masz rację co do operatora połowowego i zdolności do zrobienia czegoś po wystąpić błędy ...

chciałbym wykorzystać operator catch złapać błąd i coś zrobić:

const stream = Observable.interval(1000) 
    .take(5) 
    .map(n => { 
    if (n === 3) { 
     throw Observable.throw(n); 
    } 
    return n; 
    }) 
    .catch(err => { 
    this.error = error; 
    (...) 
    }); 

i w szablonie:

<div>{{error}}</div> 

Aby móc przejść na początkowy zaobserwować, trzeba utwórz nowy zaczynając od momentu wystąpienia błędu:

createObservable(i) { 
    return Observable.interval(1000) 
    .range(i + 1, 5 - i) 
    .take(5 - i) 
    }); 
} 

i używać go w catch callback:

.catch(err => { 
    this.error = error; 
    return this.createObservable(err); 
    }); 

te dwa pytania mogłyby pomóc:

+0

Rozumiem, musimy użyć rura asynchroniczna, tylko wtedy, gdy jesteśmy pewni, że nie ma błędów, czy to prawda? – refactor

6

1) nie, rura async subskrybuje i anuluje subskrypcję oraz zwraca otrzymane zdarzenia. Będziesz musiał obsługiwać błędy, zanim otrzymają rurę async.

2) Możesz użyć operatora catch, a gdy zwróci on obserwowalny, zamiast jego wartości zostanie wysłana jego wartość (s) przez .catch(err => Observable.of(-1)).

Możesz użyć tego do wyemitowania specjalnej wartości "błędu", a następnie użyj czegoś w rodzaju *ngIf="num === -1, aby pokazać wartość błędu w jakiś specjalny sposób.

można znaleźć więcej informacji na temat tej https://blog.thoughtram.io/angular/2017/02/27/three-things-you-didnt-know-about-the-async-pipe.html