Angular 2 - 在单个observable上处理多个订阅

Tom*_*ron 27 javascript rxjs angular2-http angular

我正在开发一个Angular 2应用程序,需要一些关于如何干净地处理身份验证错误的指导.

我的最终目标是能够集中处理每个Http请求的身份验证错误(特别是401和403).

我发现这个问题对于让我开始非常有帮助,但是我仍然坚持为我的自定义Http实现返回的每个observable注册我的错误处理程序的正确方法.

以下是我目前正在使用的示例:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的解决方案"工作"只有一个故障......每个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

use*_*222 31

这可能是因为您Observable<Response>是一个冷可观察的事实,即它为每个新用户"重新启动".有关热与冷可观测量的解释,请看一下冷热观测值:是否存在"热"和"冷"运算符?.所以在这里你可能为结果处理程序订阅一次,为错误处理程序订阅另一次.

您应该能够通过"共享"您的observable来解决订阅副作用,

即替换

var response = super.get(url, options);
Run Code Online (Sandbox Code Playgroud)

var response = super.get(url, options).share();`
Run Code Online (Sandbox Code Playgroud)