使用angular和rxjs可配置的轮询间隔

时间:2019-04-19 03:07:40

标签: angular rxjs angular-httpclient ajax-polling

我正在尝试使用rxjs和angular创建连续轮询。以下是我的要求的实现。

https://stackblitz.com/edit/angular-sq3ke5

ngOnInit() {
    const bitcoin$ = this.http.get('https://blockchain.info/ticker');


    this.polledBitcoin$ = timer(0, this.timeInterval).pipe(
        merge(this.manualRefresh),
        concatMap(_ => bitcoin$),
        map((response: {EUR: {last: number}}) => {
          console.log(new Date() +" >> " + response.EUR.last)
          return response.EUR.last;
          }),
      );
  }

但是,在此示例中,我添加了轮询间隔,并且希望基于用户输入的值对其进行更新。但是,文本输入中的任何更改都不会反映在轮询间隔中。 有人可以帮助我达到这个结果吗?

谢谢。

1 个答案:

答案 0 :(得分:2)

更新timeInterval变量不仅会更新您的interval Observable,还必须杀死它并启动一个新的Observable。

尝试这种方法:

<input [ngModel]="timeInterval" (ngModelChange)="changeInterval($event)" />
Bitcoin price: {{ dataToShow }}


ngOnInit() {
  this.startInterval();
}

startInterval() {
  const bitcoin$ = this.http.get('https://blockchain.info/ticker');
  this.polledBitcoin$ = timer(0, this.timeInterval).pipe(
      merge(this.manualRefresh),
      concatMap(_ => bitcoin$),
      map((response: {EUR: {last: number}}) => {
        console.log(new Date() +" >> " + response.EUR.last)
        return response.EUR.last;
        }),
    );

    this.sub = this.polledBitcoin$.subscribe((data) => {
      this.dataToShow = data;
    });
}

changeInterval(e) {
  this.timeInterval = e;
  if (this.sub) {
    this.sub.unsubscribe();
  }
  this.startInterval();
}

https://stackblitz.com/edit/angular-4n29cm?file=app%2Fapp.component.ts

修改

更有效的方法是等待输入更改,然后再次重新创建间隔。我已经使用主题来侦听输入中的更改,请等待一段时间,以便用户完成输入,然后重新启动间隔。

ngOnInit() {
  this.startInterval();
  this.inputSub = this.inputSubject.pipe(debounceTime(500)).subscribe(() => {
    console.log('restart now')
    if (this.intervalSub) {
        this.intervalSub.unsubscribe();
    }
    // you probably don't want an interval running in zero second interval
    // add more checks here if you want, for example: this.timeInterval > 200
    if (this.timeInterval) {
      this.startInterval();
    }
  })
}

startInterval() {
  const bitcoin$ = this.http.get('https://blockchain.info/ticker');
  this.polledBitcoin$ = timer(0, this.timeInterval).pipe(
      merge(this.manualRefresh),
      concatMap(_ => bitcoin$),
      map((response: {EUR: {last: number}}) => {
        console.log(new Date() +" >> " + response.EUR.last)
        return response.EUR.last;
        }),
    );

    this.intervalSub = this.polledBitcoin$.subscribe((data) => {
      this.dataToShow = data;
    });
}

changeInterval(e) {
  console.log("change interval called");
  this.timeInterval = e;
  this.inputSubject.next(e);
}

https://stackblitz.com/edit/angular-c355ij?file=app%2Fapp.component.ts