Joseph S
Joseph S

Reputation: 330

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

Upvotes: 1

Views: 917

Answers (2)

satanTime
satanTime

Reputation: 13539

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);
        });

Upvotes: 1

Valeriy Katkov
Valeriy Katkov

Reputation: 40612

It's better to use combineLatest() in this case instead of merge():

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

Upvotes: 1

Related Questions