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;
    }
}

person Tombatron    schedule 28.01.2016    source источник


Ответы (1)


Вероятно, это связано с тем, что ваш Observable<Response> является холодным наблюдаемым, т.е. он «перезапускается» для каждого нового подписчика. Для объяснения горячих и холодных наблюдаемых см. Горячие и холодные наблюдаемые: существуют ли "горячие" и "холодные" операторы?. Итак, здесь вы, вероятно, подписываетесь один раз на обработчик результатов, а другой раз на обработчик ошибок.

Вы должны иметь возможность обойти побочный эффект подписки, «поделившись» своим наблюдаемым,

то есть заменить

var response = super.get(url, options);

С

var response = super.get(url, options).share();`
person user3743222    schedule 28.01.2016
comment
Спасибо .. это именно то, что я искал - person prashanth yet; 07.12.2017