Problem
我订阅了两次httpClient.get observable . 但是,这意味着我的调用会被执行两次 . 为什么是这样?
Proof
对于我做的每个订阅(),我在登录页面中得到另一行 .
Code (onSubmit() from login page button)
var httpHeaders = new HttpHeaders()
.append("Authorization", 'Basic ' + btoa(this.username + ':' + this.password));
var observable = this.httpClient.get('api/version/secured', { headers: httpHeaders});
observable.subscribe(
() => {
console.log('First request completed');
},
(error: HttpErrorResponse) => {
console.log('First request error');
}
);
observable.subscribe(
() => {
console.log('Second request completed');
},
(error: HttpErrorResponse) => {
console.log('Second request error');
}
);
Console
zone.js:2935 GET http://localhost:4200/api/version/secured 401 (Unauthorized)
login.component.ts:54 First request error
zone.js:2935 GET http://localhost:4200/api/version/secured 401 (Unauthorized)
login.component.ts:62 First request error
Irrelevant background
我有一个LogonService对象来处理我的登录功能 . 它包含一个布尔变量,显示我是否登录 . 每当我调用login函数时,它都会订阅httpClient.get的observable,将login变量设置为true或false . 但是login函数也返回了可以被订阅的observable . 花了我一些时间将双重请求链接到双重订阅 . 如果有更好的方法来跟踪登录而不是通过变量,请告诉我!我正在努力学习角:)
4 回答
尝试在
HttpClient.get
的结果上使用share运算符,如下所示:您需要在脚本之上添加以下导入:
share
运算符产生一个可观察的hot
,即在订阅者之间共享 . 但是还有更多内容,我建议this article深入潜水(你当然也可以谷歌hot vs cold observables
找到更多) .你的观察是冷的:
你需要
multicast
你的Observable,或者换句话说,让它变热:为此,您可以使用share运算符,但它仍然不能保证您单个http调用 . 分享将
multicast
您的观察,使其在订阅者之间共享,但一旦http呼叫完成,它将为新订阅者进行新的http呼叫 .如果你想要一个缓存行为(执行一次调用,然后在订阅时为每个订阅者提供值),你应该使用
publishReplay().refCount()
.进一步阅读:
Publish and share operators
除了上述答案,您还可以将
http
服务分配给observable,然后订阅获取数据 . 例如:The Angular documentation.
http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html