所以我使用Angular 2并努力使HTTP请求可观察,以便在多个观察者之间共享。更具体地说,我想分享所有的响应类型,包括错误。
我尝试过这样:
return this._http.request(new Request(options))
.map((res: Response) => this.refreshToken(res))
.share()
然后
this.data.request()
.map((response: Response) => (new financeiro.FetchCompletedAction(response)))
.catch((error: any) => {
console.log('lancamento-effects:');
return Observable.of(new feedback.HttpRequestFailedAction(["Erro ao inserir lançamento"]))
})
上面的代码用于发送错误操作,最终在用户屏幕上显示错误消息。
实际上这发生了两次......
它也会在控制台上打印两次。
答案 0 :(得分:2)
以下是一些代码(Plunkr):
@Component({
selector: 'my-app',
template: `
<button (click)="subscribe()">Subscribe</button>
`
})
export class AppComponent {
obs: Observable<any>;
constructor(private http: Http) {
// Create the observable ONCE + Share.
this.obs = this.http.get('https://httpbin.org/get')
.do(() => console.log('***SIDE EFFECT***'))
.mapTo('***RESULT***')
.share();
}
subscribe() {
// Subscribe to the same observable TWICE.
this.obs.subscribe(val => console.log('subs1', val));
this.obs.subscribe(val => console.log('subs2', val));
}
}
以下是控制台显示的内容:
***SIDE EFFECT***
subs1 ***RESULT***
subs2 ***RESULT***
一个副作用(即HTTP请求),两个订阅。
这就是你要找的东西吗?
答案 1 :(得分:0)
确保每个订阅者订阅相同的热点可观察对象。每次打电话:
return this._http.request(new Request(options))
.map((res: Response) => this.refreshToken(res))
.share()
您正在从冷观察中创建一个新的热观察。
假设上面的代码包含在一个名为foo()的函数中的示例:如果执行以下操作,您将创建2个热可观察对象和2个http请求:
foo().subscribe(...)
foo().subscribe(...)
以下只会创建一个热的可观察(和单个http请求):
let hotObs = foo();
hotObs.subscribe(...)
hotObs.subscribe(...);
答案 2 :(得分:0)
您需要了解冷/热可观察对象。
冷的Observable 是一个Observable,它在每次订阅时都会重新执行其订阅处理程序:
const cold = new Observable(function subscribe(observer) {
console.log('subscribed');
observer.next(Math.random());
observer.complete();
});
// > subscribed
// sub 1: 0.1231231231231
cold.subscribe((num) => console.log('sub 1:', num));
// > subscribed
// sub 2: 0.09805969045
cold.subscribe((num) => console.log('sub 2:', num));
热可观察是可观察的源(冷或其他),在源和订阅者之间具有主题。订阅热的Observable时,订阅将在内部透明地路由到内部Subject,并且Subject订阅了源Observable。这样可以确保源Observable仅具有一个订阅者(主题),并且主题与许多订阅者共享源的值:
const cold = new Observable(function subscribe(observer) {
console.log('subscribed');
observer.next(Math.random());
observer.complete();
});
const hot = cold.publish();
hot.subscribe((num) => console.log('sub 1:', num));
hot.subscribe((num) => console.log('sub 2:', num));
hot.connect(); // <-- this subscribes the inner Subject to the cold source
// > subscribed
// > sub 1: 0.249848935489
// > sub 2: 0.249848935489
您可以通过多播使Observable成为热点,该多播具有一个函数,该函数可在连接主题时返回要使用的主题。为方便起见(例如发布),多播也有一些变体,可以创建特定类型的主题。 publish()
是multicast(() => new Subject())
除了connect()
(使内部Subject订阅源并返回基础Subscription)之外,您还可以调用refCount()
,后者返回Observable。由refCount()
返回的Observable订阅一次后,它将在内部自动调用connect()
,后续的订阅将不会重新连接。当所有订阅者都取消订阅时,refCount
将自动从源中取消订阅内部主题。 share()
是source.publish().refCount()
的一种便捷方法。
所以,两者的工作方式相同,
const a = Rx.Observable.create().share();
const b = new Rx.Subject();