angular - RxJs 可观察 : How to intercept a cold observable?

标签 angular rxjs

我正在构建一个 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/

相关文章:

javascript - 如何创建 Angular 服务以从本地存储获取数据(如果可用),否则调用 api 方法

css - 动画背景颜色,如 Angular2 中 div 内的进度条

javascript - 是否可以在 Web Worker 中创建 signalR 流连接

angular - AngularJS 2 中的 InterpolateProvider

angular - 如何在一系列 API 调用中正确链接可观察对象

typescript - switchMap 到 switchMapTo

仅当第一个可观察对象为空时, Angular rxjs 才订阅第二个可观察对象

javascript - RxJS 根据外部条件从流中提取数据

javascript - 操作必须具有类型属性

angular - 如何拦截:enter & :leave Animations in Angular with a changes Diff?