2016-07-06 57 views
12

Sto utilizzando il tubo asincrono Angular2 per trasmettere i valori nel DOM. Ecco un esempio reale semplice:Gestione degli errori con il tubo asincrono 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> 

Quello che vorrei fare è di avere la sequenza di 1-5 visualizzati, ma sulla voce di errore (3), in qualche modo popolare la #error div con il messaggio di errore.

Questo sembra richiedere due cose: prima è la capacità del tubo asincrono angolare di fare qualcosa di intelligente con errori, di cui non vedo alcun segno. Guardando il codice sorgente, apparentemente lancia un'eccezione JS, che non sembra troppo amichevole.

Secondo è la possibilità di riavviare o continuare la sequenza dopo l'errore. Ho letto su catch e onErrorResumeNext e così via, ma tutti coinvolgono un'altra sequenza che verrà commutata su un errore. Ciò complica enormemente la logica della generazione del flusso, sul quale vorrei semplicemente inserire una serie di numeri (in questo semplice esempio). Ho la sensazione di affondare che una volta che si verifica un errore il gioco è finito e l'osservabile è completato e può essere "riavviato" solo con un altro osservabile. Sto ancora imparando osservabili; è questo il caso?

Quindi la mia domanda è duplice:

  1. possibile reindirizzare asincrona di Angular2 fare qualcosa di intelligente con errori?
  2. Gli osservabili hanno un modo semplice per continuare dopo un errore?

risposta

9

Sì hai ragione per quanto riguarda l'operatore cattura e la capacità di fare qualcosa dopo si verificano errori ...

vorrei sfruttare l'operatore catch per catturare l'errore e fare qualcosa:

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

e nel modello:

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

Per essere in grado di andare sul osservabile iniziale, è necessario creane uno nuovo a partire dal punto in cui si verifica l'errore:

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

e utilizzarlo nel catch callback:

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

Queste due domande potrebbero aiutare:

+0

La mia comprensione è che abbiamo bisogno di usare tubo asincrono, solo quando siamo sicuri che non ci sono errori, è corretto? – refactor

6

1) no, la pipe async sottoscrive e disiscrive e restituisce gli eventi ricevuti. Dovresti gestire gli errori prima che ricevano la pipe async.

2) È possibile utilizzare l'operatore di cattura e quando restituisce un osservabile, il suo valore (i) viene emesso dallo .catch(err => Observable.of(-1)) anziché dall'errore.

È possibile utilizzare questo per emettere un valore speciale "errore" e quindi utilizzare qualcosa come *ngIf="num === -1 per mostrare il valore dell'errore in qualche modo speciale.

Potete trovare ulteriori informazioni su questo https://blog.thoughtram.io/angular/2017/02/27/three-things-you-didnt-know-about-the-async-pipe.html