Angular 角度2-如何更改RxJS可观测值的间隔

Angular 角度2-如何更改RxJS可观测值的间隔,angular,rxjs,observable,rxjs5,Angular,Rxjs,Observable,Rxjs5,我使用rxJS Observable Interval刷新正在获取的数据。我想不出改变间隔设置的方法。我已经看到了一些关于使用rxJS提供的主题类的东西,但是我无法让它工作 我在本文中提供了一个简化的示例 在AppComponent中,我有这个方法 getTime() { this.timeService.getTime(this.refreshInterval) .subscribe(t => { this.currentTim

我使用rxJS Observable Interval刷新正在获取的数据。我想不出改变间隔设置的方法。我已经看到了一些关于使用rxJS提供的主题类的东西,但是我无法让它工作

我在本文中提供了一个简化的示例

在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)
}

也许有人能给我一个工作的例子,这将是伟大的

我从您的plnkr中了解到,您的目标是允许用户修改计时器间隔

您预计,refreshInterval的更改将更改rxJs的声明流:

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

每次更新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.一个可观察的链,使用连续重新执行流:

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()
都会返回一个新的可观察对象,并且新的可观察对象将根据当前设置的间隔等待,然后再发出


我想在前面的答案(以及其他关于堆栈溢出的答案)的基础上进行构建。我的示例有一个通用的
刷新服务
,各种组件都可以用于订阅。这样,一个站点可以有一个“每X秒刷新一次”组件,每个组件都可以订阅该组件

该服务提供具有刷新功能的
,该功能提供可观察的
。它利用了
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)
      );
  }
}

实际上,这个答案可能不准确。经过一段时间的努力后,我能够在不破坏和重新创建流的情况下实现所述目标,这是我自己对代码的一个主要警告,当我缩短间隔时,我希望它以新值再次运行,并以更短的间隔重复。在您的演示中,如果将间隔设置为10分钟,然后将其设置为1秒,我必须等待10分钟才能看到更新。Hi@Arvand代码的行为与描述的操作相同。遵守指示的时间间隔,然后下一个时间间隔才会生效。如果您希望延迟更改立即取消当前运行的间隔,并用新间隔取代它,可以这样做,但您要求的是不同的内容。回答很好!但是为什么你需要两张开关图呢?
this.refreshService
  .withRefresh()
  .switchMap(() => /* do something on each interval of the timer */);