具有角度和rxjs的可配置轮询间隔

问题描述 投票:1回答:1

我正在尝试使用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;
          }),
      );
  }

但是在这个例子中,我添加了轮询间隔,我希望它根据用户输入的值进行更新。但是,文本输入中的任何更改都不会反映在轮询间隔中。有人可以帮我实现这个结果吗?

提前致谢。

angular rxjs angular-httpclient ajax-polling
1个回答
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

编辑

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

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

© www.soinside.com 2019 - 2024. All rights reserved.