If your costlyProcess is really something that is costly in terms of CPU and needs to be run in the background in order not to freeze the UI, then RxJS is not what will help you. You need to either do it on the server, or to use a web worker.
If it's costly because it makes one or several requests to a backend, then it should return an Observable, and you can then use something like this:
import {
BehaviorSubject,
combineLatest,
tap,
debounceTime,
startWith,
map, switchMap, of, delay,
} from 'rxjs';
let data1$ = new BehaviorSubject<number>(0);
let data2$ = new BehaviorSubject<number>(0);
let data3$ = new BehaviorSubject<number>(0);
function costlyProcess(data1: number, data2: number, data3: number) {
return of('result').pipe(delay(3000));
}
type DataState<T> =
| { state: 'Loading' }
| { state: 'Error'; error: Error }
| { state: 'Ok'; data: T };
let updateState$ = combineLatest({
data1: data1$,
data2: data2$,
data3: data3$,
}).pipe(
debounceTime(1000),
switchMap(({data1, data2, data3}) =>
costlyProcess(data1, data2, data3).pipe(
map(() => {
return {
state: 'Ok',
data: undefined,
} as DataState<undefined>;
}),
startWith({ state: 'Loading' } as DataState<undefined>)
)
)
);
updateState$.subscribe();