2016-02-27 167 views
11

我创建了一个服务,使一个简单的GET请求进行多次:Http请求在Angular2服务

private accountObservable = null; 

constructor(private _http: Http) { 
} 

getAccount() { 
    // If we have account cached, use it instead 
    if (this.accountObservable === null) { 
     this.accountObservable = this._http.get('http://localhost/api/account') 
      .map(res => <Account> res.json().data) 
      .catch(this.handleError); 
    } 

    return this.accountObservable; 
} 

我已经补充说,在我的引导功能,服务于全球提供它(我的希望是提供相同的实例到所有组件):

provide(AccountService, { useClass: AccountService }) 

问题是当我在不同的组件中调用此服务时,每次都会发出GET请求。所以,如果我将它添加到3个组件,即使我检查一个observable是否已经存在,也会发出3个GET请求。

ngOnInit() { 
    this._accountService.getAccount().subscribe(
    account => this.account = account, 
    error => this.errorMessage = <any>error 
); 
} 

如何防止GET请求被多次执行?

+1

您是否只提供引导级别的服务? (这听起来像你可能将它列入所有组件的'providers'数组中,这将创建3个服务实例。如果您只在引导级别提供它,请尝试使用[Observable.share()](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/share.md) 。 (这些都只是我的猜测。) –

+1

另请参阅http://stackoverflow.com/a/35527616/215945,以获取缓存服务器结果的稍微不同的实现。 –

+1

是的,我只在引导程序中提供''提供'。我已经尝试在服务的构造中添加console.log(),并且它仅被触发一次。我在'get()'之后加了'share()',但没有什么区别。另一篇文章也没有工作。我想这是因为在我们收到数据之前,会有新的请求。因此,如果3个组件同时运行getAccount(),则所有请求都会发出,直到其中一个响应成功为止。 – Christoffer

回答

19

使用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开发人员工具网络选项卡显示一个HTTP请求data.json。有share()注释掉了,有4个请求。

+6

这是行不通的。之前看到这个问题,而这个解决方案再次看到它,解决方案仍然无法工作。 –

+0

另外不要忘记添加'进口'rxjs /添加/运营商/共享';'@ RickO'Shea这个答案很好。如果它不适合你,那么你可能想发布一个演示你的问题的plunkr。 – jlh

2

有两种类型的可观察量。

冷可观察到:每个用户收到的所有事件(从一开始)

热点观察到:每个用户接收所有订阅后emited的事件。

冷观察是默认的。这就是多次触发WS调用的原因。

为了使可观察到的热点,你必须使用下面的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(); 
} 
+1

但是每次调用getAccount()时都不会导致HTTP请求? –

+1

有一个错误'属性'发布'不存在类型'Observable '。' –