Я пытаюсь построить подключаемый модуль ProgressService
.
Служба должна отслеживать, сколько «вещей» загружается в данный момент. И есть метод isLoading()
, который возвращает Observable<boolean>
, чтобы указать, загружается ли что-либо вообще.
Мое первое решение было очень наивным с использованием new BehaviorSubject(0)
, а затем каждый провайдер загрузки просто звонил ProgressService.increase()
и ProgressService.decrease()
. Это работало нормально. Но теперь я хотел бы стать более реактивным, если это возможно.
Затем я наткнулся на merge
, который прекрасно работает, когда все поставщики загрузки известны в начале:
this.progress = merge(...progressProviders).pipe(
scan((acc, curr) => acc + (curr ? 1 : -1), 0)
);
Это просто увеличит / уменьшит значение progress
, когда какой-либо провайдер загрузки выдаст true
или false
.
Но мне также нужна какая-то функция регистрации / отмены регистрации. В основном это должно добавить новую Observable
в цепочку merge
(или удалить ее).
Новый ProgressService
должен выглядеть так:
class ProgressService {
progress: Observable<number> = EMPTY; // value > 0 when something is loading
addLoadingProvider(lp: Observable<boolean>) {
// increment this.progress, when lp emits true
// decrease this.progress, when lp emits false
// nice to have: ignore if lp's first emitted value is false
}
removeLoadingProvider(lp: Observable<boolean>) {
// stop listening to lp
// clean up: decrease this.progress, if lp last emitted true
}
isLoading(): Observable<boolean> {
return this.progress.pipe(
map(val => val !== 0)
);
}
}
Может быть, метод removeLoadingProvider
вообще не нужен (?), Если мы возвращаем Subscription
из addLoadingProvider
и используем Subscription.unsubscribe()
для отмены регистрации.
Надеюсь, кто-нибудь подскажет, как merge
и unmerge
дополнительные Наблюдаемые по требованию.