如何确保来自不同组件的 Observable 是完整的?

How to ensure observables from different components are complete?

我在一个页面上有很多组件,它们都使用可观察对象来获取 API 数据。我将这些 observables 传递给加载服务,我想显示从传递第一个 observable 到最后一个 observable 完成的加载程序。

正在加载服务:

    private _loading = new BehaviorSubject<boolean>(false);
    readonly loading$ = this._loading.asObservable();

    showUntilLoadingComplete<T>(observable$: Observable<T>): Observable<T> {
      return of(null).pipe(
        tap(_ => this._loading.next(true)),
        concatMap(_ => observable$),
        finalize(() => this._loading.next(false))
      );
    }

我的组件然后像这样调用加载服务:

    this.loadingService.showUntilLoadingComplete(someObservable$)
        .subscribe(data=> {
           // do stuff
        });

但是,由于第一个可观察到的最终确定,行为主题被传递为 false,这反过来又阻止了加载程序的显示。我考虑过创建另一个行为主题来存储活动可观察对象的数组,并在完成后从此处删除它们,然后订阅它并在数组没有长度时关闭加载程序。但这似乎不是一个很好的解决方案,所以我正在寻找其他人的意见。

由于您在单例服务中依赖于相同的 loading$ Observable,因此您可以添加另一个 属性 来反映 active 调用次数,然后将 loading 仅在没有其他活动呼叫时关闭。

尝试如下操作:

private _active: number = 0;
private _loading = new BehaviorSubject<boolean>(false);
readonly loading$ = this._loading.asObservable();

showUntilLoadingComplete<T>(observable$: Observable<T>): Observable<T> {
  return of(null).pipe(
    tap(() => {
      this._loading.next(true);
      this._active++;
    }),
    concatMap((_) => observable$),
    finalize(() => {
      this._active--;
      if (!this._active) {
        this._loading.next(false);
      }
    })
  );
}