需要我的服务人员知道所有组件异步操作何时结束

时间:2019-05-30 11:25:51

标签: angular asynchronous rxjs observable

我有一个拥有Observable的角度服务。我订阅了多个(可变数量)响应执行异步操作的组件。我需要我的服务才能知道所有这些组件异步操作何时结束。

这是我的处境:

过滤服务

...

appliedFilter$: Observable<FormattedFilter[]> = new Observable<FormattedFilter[]>(
    o => (this.appliedFilter = o)
  ).pipe(shareReplay(1));
  private appliedFilter: Observer<FormattedFilter[]>;

  onFiltersApplied(filters: Filter[]): void {
    if (this.appliedFilter) {
      const formattedFilters = this.formatFilters(filters);
      this.appliedFilter.next(formattedFilters);
    }
  }

...

可过滤组件1

...

this.filterService.appliedFilter$.subscribe(filters => {
  // multiple pipelined async operations
});

...

可过滤组件2

...

this.filterService.appliedFilter$.subscribe(filters => {
  // multiple pipelined async operations
});

...

可过滤组件3

...

this.filterService.appliedFilter$.subscribe(filters => {
  // multiple pipelined async operations
});

...

因此,我需要的是筛选服务,以通知所有组件何时都通过AppliedFilter $ Observable应用了接收到的筛选器,以及何时最终加载了所有筛选数据。

这样做的目的是防止用户在所有组件完成过滤过程之前更新过滤器。

谢谢!

1 个答案:

答案 0 :(得分:1)

您确定要等到组件将被更新而不是分别更新组件来过滤更改时,才确定吗? 大多数美观,用户友好的应用程序方法似乎有所不同: 如果在应用新过滤器时某些组件未完成更新-则更新将被取消并重新开始。

对于您而言,可以使用rxjs switchMap运算符来实现。该运算符使您可以按照我刚才所说的去做-放弃当前的异步操作,并在出现新的发出时重新开始。

这里是一个例子:

...

this.filterService.appliedFilter$
    .pipe(
        switchMap(
            filters => { return yourObservableChain()} // chain is your async opeartions
        )
    )
    .subscribe(); // you have only the most relevant values here

...

那么,怎么回事:

  1. 应用新过滤器时,将调用yourObservableChain(它可以是http请求,也可以是您所说的其他任何事情(异步操作)。
  2. 如果在这些操作期间再次应用了新的过滤器-那些旧的过滤器将被忽略,则呼叫将被取消,新的操作将开始。
  3. 只有最相关的结果才是subscribe

注意,switchMap 必须返回一个可观察的对象。这是在Angular范围内使用它的另一个简短示例(带有http调用)。

import { switchMap } from 'rxjs/operators'; // don't forget

... your components code:...

this.triggerSubject$.pipe( // assume this emits with some urls
    switchMap(data => { // assume new url is a prop of data
      return this.http.get(data.URL); // returns observable
    })
).subscribe(results => {
   // having only fresh results here
   // because switchMap cancelled other requests
   console.log(results) // or do whatever you need
})