我正在构建一个 Angular 2 应用程序 - 我想要的东西之一是一个加载指示器组件,每次运行 http 请求时它都是可见的。
我构建了自己的可注入(inject) RestService,它包装了 Http 服务。
我的 RestService 公开了“get()”和“post()”等方法,内部调用 Http.get() 或 Http.post()。现在的计划是拦截调用以服务我自己的一组 Observables(实际上是主题),我将其称为“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() 返回冷可观察值有关。现在,“subscribe()”两次,调用就会进行两次。
为了避免这种行为,我最终执行了以下操作:
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);
}
它工作得很好......但是在没有实际映射任何东西的情况下使用“map()”感觉很奇怪......对于这种事情有更好的替代运算符吗?
最佳答案
使用 map 可以解决问题,但还有更好更正确的解决方案。假设您的调用失败,则永远无法到达 map ,并且您永远不会知道您的调用失败,从而导致旋转器继续运行。
你能做的最好的事情就是用finally替换map函数。这看起来像这样:
public get(url: string): Observable<any> {
let request = this.get(url)
.catch(this.handleError)
.finally(() => this.requestFinished.next());
return this.intercept(request);
}
finally 总是被执行,并提供将完成您在这里期望的一切的行为。
关于angular - RxJs 可观察 : How to intercept a cold observable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40654245/