Angular 2 - 处理单个可观察对象的多个订阅
Angular 2 - Handling multiple subscriptions on a single observable
我正在开发 Angular 2 应用程序,需要一些有关如何干净地处理身份验证错误的指导。
我的最终目标是能够集中处理每个 Http
请求的身份验证错误(特别是 401 和 403)。
我发现 问题对我的入门非常有帮助,但是我仍然不知道为自定义 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;
}
}
上面的解决方案"works" 很顺利...每个 HTTP 请求都会发出两次。那可不行。
关于如何正确执行此操作的任何指导?
(更新)工作代码
根据此处接受的答案中的信息,class 正常运行时的样子。
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;
}
}
这可能是因为您的 Observable<Response>
是冷可观察的,即对于每个新订阅者来说都是 'restarted'。有关热 vs. 冷 observables 的解释,请查看 。所以在这里您可能订阅一次结果处理程序,另一次订阅错误处理程序。
您应该能够通过 'sharing' 您的可观察对象来解决订阅的副作用,
即替换
var response = super.get(url, options);
有
var response = super.get(url, options).share();`
我正在开发 Angular 2 应用程序,需要一些有关如何干净地处理身份验证错误的指导。
我的最终目标是能够集中处理每个 Http
请求的身份验证错误(特别是 401 和 403)。
我发现 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;
}
}
上面的解决方案"works" 很顺利...每个 HTTP 请求都会发出两次。那可不行。
关于如何正确执行此操作的任何指导?
(更新)工作代码
根据此处接受的答案中的信息,class 正常运行时的样子。
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;
}
}
这可能是因为您的 Observable<Response>
是冷可观察的,即对于每个新订阅者来说都是 'restarted'。有关热 vs. 冷 observables 的解释,请查看
您应该能够通过 'sharing' 您的可观察对象来解决订阅的副作用,
即替换
var response = super.get(url, options);
有
var response = super.get(url, options).share();`