Search code examples
angularrxjsobservablereactive-programmingbehaviorsubject

Multiple RXJS BehaviorSubjects to trigger function call


I want to run a computation intensive function that depends on the latest value of 3 behaviorSubjects. Sometimes all subjects change at the same time and I do not want to run the calculation 3-times. This is how I have implemented it as of now.

this.subscription = merge(behaviorSubject1$, behaviorSubject2$, behaviorSubject3$)
        .pipe(throttleTime(300)) //this is to avoid running the function 3 times when all subjects change simultaneously
        .subscribe(() => {
           const answer = getSolution(subject1$.getValue(), subject2$.getValue(), subject3$.getValue());

        });

I am not sure if this is the best way to go about it. Any help is much appreciated


Solution

  • Depends what you want to do

    do you want to calculate based on the latest value? then your approach is fine, but use combineLatest instead, any emit will cause the calculation.

    this.subscription = combineLatest(behaviorSubject1$, behaviorSubject2$, behaviorSubject3$)
            .pipe(throttleTime(300))
            .subscribe(([o1, o2, o3]) => {
              const answer = getSolution(o1, o2, o3);
            });
    

    do you want to calculate all of them but one by one? use concatMap.

    this.subscription = combineLatest(behaviorSubject1$, behaviorSubject2$, behaviorSubject3$).pipe(
      concatMap(([o1, o2, o3]) => getSolution(o1, o2, o3)), // getSolution should be an observable.
    )
            .subscribe(solution => {
            });
    

    do you want to ignore emits during calculation? use exhaustMap.

    this.subscription = combineLatest(behaviorSubject1$, behaviorSubject2$, behaviorSubject3$).pipe(
      exhaustMap(([o1, o2, o3]) => getSolution(o1, o2, o3)), // getSolution should be an observable.
    )
            .subscribe(solution => {
            });
    

    do you want to calculate when all 3 have been changed? use zip.

    this.subscription = zip(behaviorSubject1$, behaviorSubject2$, behaviorSubject3$)
            .subscribe(([o1, o2, o3]) => {
               const answer = getSolution(o1, o2, o3);
            });