我正在构建一个Angular 2应用程序 - 我想要的一件事是一个加载指示器组件,每次运行http请求时都是可见的。
我构建了自己的可注入RestService,它包装了Http服务。
我的RestService公开类似" get()"等方法。和" post()",内部调用Http.get()或Http.post()。现在的计划是拦截调用我自己的一组Observables(实际上是主题),我打电话给#34; requestStarted"和" requestFinished"。
我尝试了以下内容:
public get(url: string): Observable<any> {
this.requestStarted.next();
let request = this.get(url)
.map(r => r.json())
.catch(this.handleError);
request.subscribe(() => this.requestFinished.next());
return request;
}
这确实产生了意想不到的结果:突然每个请求都发出两次......我相信这与Http.get()返回一个冷可观察的事实有关。现在使用&#34; subscribe()&#34;两次,调用两次。
为了规避这种行为,我最终做了以下事情:
private intercept(observable: Observable<any>): Observable<any> {
this.requestStarted.next();
observable.map(r => {
this.requestFinished.next(); // <-- USING MAP TO INTERCEPT?
return r;
});
return observable;
}
public get(url: string): Observable<any> {
let request = this.get(url)
.map(r => return r.json())
.catch(this.handleError);
return this.intercept(request);
}
效果很好......但使用&#34; map()&#34;感觉很奇怪。没有实际映射任何东西......对于这种事情,是否有更好的替代算子?
答案 0 :(得分:2)
使用map可以解决问题,但是有更好的解决方案。让我们说你的通话失败,地图永远不会到达,你永远不会知道你的通话失败,导致一个旋转器继续前进。
你能做的最好的事情就是用最后的替换map函数。这看起来像这样:
public get(url: string): Observable<any> {
let request = this.get(url)
.catch(this.handleError)
.finally(() => this.requestFinished.next());
return this.intercept(request);
}
始终执行finally,并提供将执行您期望的所有操作的行为。