我有一个拥有可观察量的角度服务。我订阅了多个(可变数量)组件,这些组件可以响应执行异步操作。我需要我的服务知道所有这些组件异步操作何时结束。
这是我的情况的一种方法:
过滤器服务
...
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
});
...
因此,我需要的是过滤器服务,以注意到所有组件何时通过applyFilter$ Observable应用了收到的过滤器,以及何时最终加载了所有过滤后的数据。
这样做的目的是防止用户在所有组件完成其过滤过程之前更新过滤器。
谢谢!
您是否确定需要等到组件更新,而不是分别更新组件以过滤更改? 在大多数不错的、用户友好的应用程序中,方法似乎有所不同: 如果在应用新筛选器时某些组件未完成更新 - 更新只是取消并启动新更新。
在您的情况下,可以使用 rxjs switchMap 运算符来实现。这个运算符允许你完全按照我刚才所说的去做 - 放弃当前的异步操作,如果新的发出,则开始新的操作。
下面是一个示例:
...
this.filterService.appliedFilter$
.pipe(
switchMap(
filters => { return yourObservableChain()} // chain is your async opeartions
)
)
.subscribe(); // you have only the most relevant values here
...
那么,这里要做什么:
- 当应用新过滤器时
yourObservableChain
被调用(它可以是http请求或你所说的任何其他事情(异步操作)。 - 如果在这些操作期间再次应用新的筛选器 - 那些旧的筛选器将被忽略,调用将被取消并启动新操作。
- 只有最相关的结果才会出现在
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
})