在Angular2服务中多次发出Http请求

时间:2016-02-27 18:20:20

标签: http angular

我创建了一个发出简单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请求?

4 个答案:

答案 0 :(得分:21)

使用Observable.share()

if (this.accountObservable === null) {
    this.accountObservable = this._http.get('./data/data.json')
      .share()
      .map(res => res.json())
      .catch(this.handleError);
}

Plunker

在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上的错误。