Home > Software engineering >  Rxjs do a job after multiple observables has completed
Rxjs do a job after multiple observables has completed

Time:06-24

Let's say I have 3 observables job1(), job2(), and job3(). I would like to call the finalJob() after all these 3 jobs has completed as the finalJob() is dependent on all 3 jobs. From what I know, I can achieve this by using Observable.forkJoin() like below:

forkJoin([this.job1(), this.job2(), this.job3()])
.subscribe(([result1, result2, result3]) => {.
    this.job1Completed = true;
    this.job2Completed = true;
    this.job3Completed = true;
    this.finalJob();
});

But the thing is I would like to run these 3 jobs simultaneously, so that each of these jobs can set their own completion status right after it has completed it's job, rather than waiting for another 2 jobs to complete then set the completion status all together, like below:

this.job1().subscribe((result1) => this.jodb1Completed = true);
this.job2().subscribe((result2) => this.jodb2Completed = true);
this.job3().subscribe((result3) => this.jodb3Completed = true);

finalJob(); // this has no guarantee all 3 jobs has completed

With the implementation above, I will not be able to call the finalJob() after all 3 jobs has completed. Is there any way to emit an event to call the finalJob() once all jobs has done?

CodePudding user response:

You can use the rxjs tap operator

forkJoin([
  this.job1().pipe(tap((result1) => this.jodb1Completed = true)),
  this.job2().pipe(tap((result2) => this.jodb2Completed = true)),
  this.job3().pipe(tap((result3) => this.jodb3Completed = true)),
])
.subscribe(response => {
  finalJob();
  console.log('done', respone)
});

CodePudding user response:

With finalize, for example. Or tap, if you want things to happen on every emission (edit: and/or if you are interested in the emitted values), not on completion (and if that makes any difference).

const stream1$ = this.job1().pipe(
    finalize(() => this.jodb1Completed = true)
);

const stream2$ = this.job1().pipe(
    finalize(() => this.jodb2Completed = true)
);

forkJoin([stream1$, stream2$]).subscribe(this.finalJob);
  • Related