简体   繁体   English

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

[英]Configurable polling interval with angular and rxjs

I am trying to create continuous polling using rxjs and angular. 我正在尝试使用rxjs和angular创建连续轮询。 Below is an implementation of my requirement. 以下是我的要求的实现。

https://stackblitz.com/edit/angular-sq3ke5 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;
          }),
      );
  }

However in this example, I have added polling interval and I want it to be updated based on the value entered by user. 但是,在此示例中,我添加了轮询间隔,并且希望基于用户输入的值对其进行更新。 However any changes in text input is not getting reflected in polling interval. 但是,文本输入中的任何更改都不会反映在轮询间隔中。 Can someone help me achieve this result? 有人可以帮助我达到这个结果吗?

Thanks in advance. 提前致谢。

Updating the timeInterval variable will not simply update your interval Observable, you will have to kill it and start a new Observable. 更新timeInterval变量不会简单地更新您的Observable interval ,您将不得不杀死它并启动一个新的Observable。

Try this approach: 试试这个方法:

<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 https://stackblitz.com/edit/angular-4n29cm?file=app%2Fapp.component.ts

Edit 编辑

A more performant approach would be to wait for the input to change and then re-create the interval again. 一种性能更高的方法是等待输入更改,然后再次重新创建间隔。 I have used a Subject for listening to the changes in the input, wait for some time so that the user has finished typing and then restart the interval. 我使用了一个主题来监听输入中的更改,等待一段时间,以便用户完成输入,然后重新启动间隔。

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 https://stackblitz.com/edit/angular-c355ij?file=app%2Fapp.component.ts

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM