Наблюдаемый закрыт по ошибке


У меня есть проблема с Observable в Angular 2.

Я подписываю свой компонент на observable, а затем, когда мой сервис имеет новое значение, мой компонент уведомляется.
Проблема в том, что когда наблюдатель нажимает ошибку, например ошибку HTTP, моя наблюдаемая закрывается, поэтому мой компонент больше не уведомляется.

Вопрос
Как я могу сделать, чтобы мой компонент продолжал прослушивать мой сервис, даже если у меня есть ошибка ?

Пример
Здесь пример

Вот мой код:

Компонент

constructor(private appService: AppService) {
    //I subscribe my component to an observable
    this.appService.commentsObservable.subscribe((comments) => {
        console.log(comments);
    }, (err) => {
        console.log(err);
    });
}

getComments() {
    //I ask the service to pull some comments
    this.appService.getComments()
}

Сервис

private commentsObserver: Observer<any>;
commentsObservable: Observable<any>;

constructor() {
    this.commentsObservable = new Observable((observer) => {
        this.commentsObserver = observer;
    });
}

getComments() {
    setTimeout(() => {
        //You will see the result displayed by the component
        this.commentsObserver.next([]);
    }, 0);

    setTimeout(() => {
        //You will see the result displayed by the component
        this.commentsObserver.next([]);
    }, 500);

    setTimeout(() => {
        //You will see the error displayed by the component
        this.commentsObserver.error({_body: 'Nice errroorr'});
    }, 1000);

    setTimeout(() => {
        //You won't see this one, why ?
        this.commentsObserver.next([]); 
    }, 1500);
}
1 4

1 ответ:

Это и есть ожидаемое поведение. Согласно документации,

В наблюдаемом исполнении могут быть доставлены следующие уведомления от нуля до бесконечности. Если будет доставлено либо сообщение об ошибке, либо полное уведомление, то больше ничего не может быть доставлено впоследствии.

Для приведенного выше кода это может быть

this.appService
// error is caught, but the observable is completed anyway
.catch((err) => {
    console.error(err)
    return Observable.empty();
})
// re-subscribe to completed observable
.repeat()
.subscribe((comments) => console.log(comments));

Но, учитывая ожидаемое поведение, непрактично использовать обработку ошибок RxJS для обеспечения непрерывной наблюдаемой некритической ошибки ценности. Вместо этого его можно изменить на

setTimeout(() => {
    //You will see the error displayed by the component
    this.commentsObserver.next(new Error('Nice errroorr'));
}, 1000);

И

this.appService.commentsObservable.subscribe((comments) => {
    if (comments instanceof Error)
        console.error(comments);
    else
        console.log(comments);
});

Этот подход может варьироваться в зависимости от фактического случая.