Обработка ошибок с помощью асинхронной трубки Angular2
Я использую асинхронный канал Angular2 для потока значений в DOM. Вот простой пример:
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>
Что бы я хотел сделать, так это отобразить последовательность 1-5, но в элементе ошибки (3) каким-то образом заполнить #error
div сообщением об ошибке.
Это, по-видимому, требует двух вещей: во-первых, способность асинхронного канала Angular делать что-то интеллектуальное с ошибками, которое я не вижу. Глядя на исходный код, по-видимому, он генерирует исключение JS, которое не выглядит слишком дружелюбным.
Во-вторых, это возможность перезапуска или продолжения последовательности после ошибки. Я читал о catch
и onErrorResumeNext
и т.д., Но все они связаны с другой последовательностью, на которую будет включена ошибка. Это значительно усложняет логику генерации потока, на котором я хотел бы просто поместить ряд чисел (в этом простом примере). У меня есть ощущение тонуса, что, как только возникает ошибка, игра завершена, и наблюдаемое завершено и может быть только "перезапущено" с другим наблюдаемым. Я все еще изучаю наблюдаемые; это на самом деле случай?
Итак, мой вопрос двоякий:
- Может ли Angular2 асинхронная труба сделать что-то умное с ошибками?
- Есть ли у наблюдателей некоторый простой способ продолжить работу после ошибки?
Ответы
Ответ 1
Да, вы правы в отношении оператора catch и способности что-то делать после ошибок...
Я бы использовал оператор catch
, чтобы поймать ошибку и сделать что-то:
const stream = Observable.interval(1000)
.take(5)
.map(n => {
if (n === 3) {
throw Observable.throw(n);
}
return n;
})
.catch(err => {
this.error = error;
(...)
});
и в шаблоне:
<div>{{error}}</div>
Чтобы иметь возможность перейти к исходному наблюдаемому, вам нужно создать новый, начиная с того места, где происходит ошибка:
createObservable(i) {
return Observable.interval(1000)
.range(i + 1, 5 - i)
.take(5 - i)
});
}
и использовать его в обратном вызове catch
:
.catch(err => {
this.error = error;
return this.createObservable(err);
});
Эти два вопроса могут помочь вам:
Ответ 2
1) no, труба async
подписывает и отменяет подписку и возвращает полученные события. Вам нужно будет обрабатывать ошибки, прежде чем они получат трубку async
.
2) Вы можете использовать оператор catch и когда он возвращает наблюдаемый, тогда его значение (и) испускается вместо .catch(err => Observable.of(-1))
вместо ошибки.
Вы можете использовать это, чтобы испустить специальное значение "ошибка", а затем использовать что-то вроде *ngIf="num === -1
, чтобы показать значение ошибки каким-то особым образом.
Вы можете найти дополнительную информацию об этом https://blog.thoughtram.io/angular/2017/02/27/three-things-you-didnt-know-about-the-async-pipe.html