如何确保来自不同组件的 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);
}
})
);
}
我在一个页面上有很多组件,它们都使用可观察对象来获取 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);
}
})
);
}