Ну, есть много способов снять кожу с кошки.Некоторые из них более элегантны, чем другие.Я предпочитаю сводить количество дополнительных наблюдаемых свойств к минимуму, который в данном случае кажется равным 2. Я бы добавил свойство isRunningRequest$
, чьё значение имеет значение флага, true, если в данный момент выполняются операции.Этот флаг будет дополнен агрегацией по другой наблюдаемой asyncAction$
, которая будет использоваться для отслеживания текущих выполняемых действий:
export class AsyncActionData {
actionType: 'start' | 'end';
actionToken: string;
}
public asyncAction$ = new Subject<AsyncActionData>();
public isRunningRequest$ = new BehaviorSubject<boolean>(false);
constructor(...) {
this.asyncAction$
.pipe(
// we keep an array of currently running actions, and add
// or remove from the array according to the action type
scan((arr: string[], action: AsyncActionData) => {
return action.actionType === 'start'
? arr.concat(action.actionToken)
: arr.filter(action => action !== action.actionToken);
}, []),
map(arr => arr.length === 0 ? false : true)
)
.subscribe(requestsAreRunning => this.isRunningRequest$.next(requestsAreRunning));
}
Когда вы выполняете действие, вы отправляете события на asyncAction$
:
this.asyncAction$.next({actionType: 'start', actionToken: 'action1'});
this.http.post(...)
.subscribe(result => ...,
null,
() => this.asyncAction$.next({actionType: 'end', actionToken: 'action1'})
);
(весь код не проверен, но идея должна быть обоснованной)
См. здесь и здесь для документации по scan
оператор.