Angular 2 完成 forkJoin 5 秒后重复

Angular 2 repeat the forkJoin 5 seconds after it's completed

我想每 5 秒重复一次我的 forkJoin 方法。一旦 forkJoin 完成并返回结果,就应该启动 5 秒计时器;

这是我当前的 forkJoin:

  let getResult1 = this.myService.GetResult1(param1, param2);       // retrun Observable<Result1>
      let getResult2 = this.myService.GetResult2(param1, param3,param4);// retrun Observable<Result2>

       Observable.forkJoin(getResult1, getResult2)
            .subscribe(results => {
              this.result1 = results[0];
              this.result2 = results[1];
              .. start counting 5 seconds and then repeat this again and again
            },
            error => this.handleError(error));

我想要的时间表:

时间:0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6

操作:请求 - Res - - - - - - - - - - - -Req-...

等等:|等待 5 秒 ------> |

使用区间可观察值:

Observable.interval(5000)
          .switchMap(t => 
               Observable.forkJoin(getResult1, getResult2))
          .subscribe(results => {
            this.result1 = results[0];
            this.result2 = results[1];
          },
          error => this.handleError(error));

这将每 5 秒生成一个请求,不一定是完成后 5 秒。但它应该足够接近。如果必须正好是 5 秒,则需要采用不同的方法。

我不确定这是否是最优雅的方式。具有更多 rxjs 经验的人可能能够提供更清晰的解决方案,但我的第一个想法是使用 Subject 来确定何时应调用 forkJoin。然后只需在 forkJoin 之后添加一个计时器来发出另一个请求。

// component.ts
subject$: Subject = new Subject();

ngOnInit(){
    this.subjectSubscription = this.subject$
        .flatMap(res => {
            return Observable.forkJoin(
                this.dummy1$, // dummy observable api
                this.dummy2$ // dummy observable api
            );
        })
        .subscribe(res => {
            // after 5 seconds, call subject.next to fire another forkJoin call
            this.timerSubscription = Observable.timer(5000).subscribe(res => {
                this.subject$.next();
            })

        });
    // make initial call
    this.subject$.next();
}

这是一个演示 plnkr (https://plnkr.co/edit/OaLIMxKKUqNXxcGp0HLW?p=preview),包括订阅清理以避免内存泄漏

在回调方法中完成代码后使用 setTimeout

export class MyComponent {

  private refreshInterval: number;
  private timeoutId: any;

  public ngOnInit(): void {
    this.refreshInterval = 5000; // 5 seconds.
    this.refresh();
  }

  private refresh(): void {
    forkJoin(
      this.service1.doThis(),
      this.service2.doThat(),
      // More calls...
    ).subscribe(results => {
      this.data1 = results[0];
      this.data2 = results[1];
      // More stuff...

      this.timeoutId = setTimeout(() => this.refresh(), this.refreshInterval);
    });
  }

  public ngOnDestroy(): void {
    if (this.timeoutId) clearTimeout(this.timeoutId);
  }

}