繁体   English   中英

Angular 2 - 如何更改RxJS Observable的间隔

[英]Angular 2 - How to change the interval of an RxJS Observable

我正在使用rxJS Observable Interval刷新正在获取的数据。 我无法弄清楚改变间隔设置的方法。 我已经看到有关使用rxJS提供的Subject类的一些内容,但我无法让它工作。

我在这个插件中提供了一个简化的例子

在AppComponent中我有这个方法。

getTime() {
        this.timeService.getTime(this.refreshInterval)
          .subscribe(t => {
            this.currentTime = t;
            console.log('Refresh interval is: ' + this.refreshInterval);
          }
        );
}

在服务组件中,我目前有这个代码。

getTime(refreshInterval: number) {
  return Observable.interval(refreshInterval)
        .startWith(0)
        .map((res: any) => this.getDate())
        .catch(this.handleError)
}

有人可能会给我一个工作的例子,这将是伟大的!

您不需要销毁并重新创建整个Observable流来更改refreshInterval 您只需要更新依赖于更改间隔的流的部分。

首先简化服务的getTime()以便它不负责确定输出的频率。 它只是返回时间:

getTime() { return (new Date()).toString(); }

现在调用代码将确定计划。 只需3个简单的步骤:

1.调整到所需间隔的源函数:

/** Observable waits for the current interval, then emits once */
refreshObs() {return Observable.timer(this.refreshInterval)}

2.使用repeat运算符连续重新执行流的可观察链:

getTime$ = Observable.of(null)
            .switchMap(e=>this.refreshObs()) // wait for interval, then emit
            .map(() => this.timeService.getTime()) // get new time
            .repeat(); // start over

3.订阅触发整个事情:

ngOnInit(){
    this.getTime$.subscribe(t => {
        this.currentTime = t;
        console.log('refresh interval = '+this.refreshInterval);
    });
}

这是因为每次重复流时refreshObs()返回一个新的observable,并且新的observable将在发出之前根据当前设置的间隔等待。

现场演示

我想在此处(以及Stack Overflow上的其他地方)建立先前的答案。 我的示例有一个通用的RefreshService ,各种组件可以使用它来进行订阅。 这样,站点可以有一个“刷新每X秒”组件,每个组件都可以订阅。

https://plnkr.co/edit/960yztjl3dqXQD2XPSei?p=preview

该服务提供了提供Observable的函数withRefresh 它利用了BehaviorSubject ,它会立即触发订阅上的事件。

export class RefreshService {

  static interval$: BehaviorSubject<number> = new BehaviorSubject<number>(30000);

  setInterval(newInterval: number){
    RefreshService.interval$.next(newInterval);
  }

  public withRefresh() {
    return RefreshService.interval$
      .switchMap((int: number) => Observable
        .interval(int)
        .startWith(0)
      );
  }
}

然后任何组件都可以使用此服务,如下所示:

this.refreshService
  .withRefresh()
  .switchMap(() => /* do something on each interval of the timer */);

据我所知,您的plnkr,您的目标是允许用户修改计时器间隔。

您期望,refreshInterval的更改将更改已声明的rxJs流:

    this.timeService.getTime(this.refreshInterval)
      .subscribe(t => {
        this.currentTime = t;
        console.log('Refresh interval is: ' + this.refreshInterval);
      }
    );

这是错的。

每次更新refreshInterval时,您需要:

  • 取消订阅或销毁以前的流。
  • 创建新流并再次订阅

暂无
暂无

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

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