我创建了一个发出简单GET请求的服务:
provide(AccountService, { useClass: AccountService })
我在我的bootstrap函数中添加了该服务以全局提供它(我希望为所有组件提供相同的实例):
ngOnInit() {
this._accountService.getAccount().subscribe(
account => this.account = account,
error => this.errorMessage = <any>error
);
}
问题是当我在不同组件中调用此服务时,每次都会发出GET请求。因此,如果我将其添加到3个组件中,即使我检查是否已存在可观察量,也会发出3个GET请求。
[[[[[[[XCUIApplication alloc] init].otherElements containingType:XCUIElementTypeNavigationBar identifier:@"UIView"] childrenMatchingType:XCUIElementTypeOther].element childrenMatchingType:XCUIElementTypeOther].element childrenMatchingType:XCUIElementTypeOther].element tap];
如何防止多次发出GET请求?
答案 0 :(得分:21)
if (this.accountObservable === null) {
this.accountObservable = this._http.get('./data/data.json')
.share()
.map(res => res.json())
.catch(this.handleError);
}
在Plunker中,AppComponent和Component2都两次调用getAccount().subscribe()
。
使用share()
,Chrome开发者工具网络标签会显示data.json
的一个HTTP请求。在share()
注释掉后,有4个请求。
答案 1 :(得分:2)
有两种类型的可观察物。
Cold Observable:每个订阅者都会收到所有事件(从头开始)
热观察:每个订阅者都会收到订阅后发出的事件。
Cold Observables是默认的。这就是WS调用被多次触发的原因。
要制作Observable Hot,您必须使用以下Rx的运营商链:
.publish().refCount()
在你的情况下:
getAccount () {
let accountObservable = this._http.get('http://localhost/api/account')
.map(res => <Account> res.json().data)
.catch(this.handleError);
return accountObservable.publish().refCount();
}
答案 2 :(得分:0)
在我的情况下,这是因为表单发布和按钮clik设置为同一侦听器
答案 3 :(得分:0)
更新的解决方案是:
1)更改您的getAccount()方法以使用share
:
getAccount () {
// If we have account cached, use it instead
if (this.accountObservable === null) {
this.accountObservable = this._http.get('http://localhost/api/account')
.pipe(share())
.map(res => <Account> res.json().data)
.catch(this.handleError);
}
return this.accountObservable;
}
2)将import { share } from 'rxjs/operators';
添加到.ts
文件的顶部,以消除share
上的错误。