Angular 2 - Обработка нескольких подписей на одном наблюдаемом
Я работаю над приложением Angular 2 и нуждаюсь в некоторых рекомендациях по устранению ошибок аутентификации.
Моя конечная цель - централизованно обрабатывать ошибки аутентификации (в частности, 401 и 403) для каждого запроса Http
.
Я нашел этот вопрос, очень полезный для того, чтобы начать меня, однако я застрял в том, чтобы правильно зарегистрировать обработчик ошибок для каждого наблюдаемого, возвращенного моим обычным Http
.
Вот пример того, с чем я сейчас работаю:
import {Injectable} from 'angular2/core';
import {Http, ConnectionBackend, Request, RequestOptions, RequestOptionsArgs, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class ClauthHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
var response = super.get(url, options);
return this._handleSecurityResponse(response);
}
/*
Other overrides omitted for brevity...
*/
private _handleSecurityResponse(response: Observable<Response>): Observable<Response> {
response.subscribe(null, (error: Response) => {
// Do some nifty error handling here.
});
return response;
}
}
Вышеупомянутое решение "работает" с одной зацепкой... Каждый HTTP-запрос выполняется дважды. Это нехорошо.
Любые указания относительно того, как правильно это сделать?
(Обновить) Рабочий код
Основываясь на информации в принятом ответе, вот что выглядит класс в его правильно функционирующей форме.
import {Injectable} from 'angular2/core';
import {Http, ConnectionBackend, Request, RequestOptions, RequestOptionsArgs, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/share';
@Injectable()
export class ClauthHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
var response = super.get(url, options);
return this._handleSecurityResponse(response);
}
/*
Other overrides omitted for brevity...
*/
private _handleSecurityResponse(response: Observable<Response>): Observable<Response> {
var sharable = response.share();
sharable.subscribe(null, (error: Response) => {
// Do some nifty error handling here.
});
return sharable;
}
}
Ответы
Ответ 1
Вероятно, это связано с тем, что ваш Observable<Response>
является холодным наблюдаемым, т.е. он перезапускается для каждого нового абонента. Для объяснения горячих и холодных наблюдаемых взгляните на Горячие и холодные наблюдаемые: есть ли "горячие" и "холодные" операторы?. Итак, здесь вы, вероятно, подписываетесь один раз для обработчика результата и в другое время для обработчика ошибок.
Вы должны уметь обходить побочный эффект подписок, "разделяя" ваши наблюдаемые,
то есть. замените
var response = super.get(url, options);
С
var response = super.get(url, options).share();`