【问题标题】:Change observable interval through input通过输入改变可观察区间
【发布时间】:2016-08-16 00:03:07
【问题描述】:

我正在使用“ping”我的服务器并返回响应时间的服务。然后我将其显示在图表中。

我的第一种方法(不能更改间隔)是这样的:

Observable.interval(2500)
        .subscribe((data) => {
          let timeStart: number = performance.now();

          this._http.get(this.url)
            .subscribe((data) => {
              let timeEnd: number = performance.now();

              let ping: number = timeEnd - timeStart;
              this.ping = ping;
              this.pingStream.next(ping);
            });
        });
}

这在我的 app.component cunstructor 中被调用:

this.pingService.pingStream.subscribe(ping => {
         this.ping = ping;
         NTWDATA.datasets[0].data.pop();
         NTWDATA.datasets[0].data.splice(0, 0, this.ping);
      })

我正在获取“ping”并将其放入我的图表数据中。工作正常。 现在我想改变间隔。 因此,我创建了一个 streamintervall.ts,它只导出一个名为 INTVL 的变量。 我尝试在这篇文章中使用答案:Change Intervall/settings of observable after creation

所以现在我处于这种状态,这是行不通的。我的图表数据从 0 开始计数。

   observable = this.pingStream.startWith(INTVL)
   .switchMap((INTVL) => { return Observable.interval(INTVL) });
       constructor(private _http: Http) {
          this.observable.map((data) => {
             let timeStart: number = performance.now();
             this._http.get(this.url)
                .subscribe((data) => {
                   let timeEnd: number = performance.now();
                   let ping: number = timeEnd - timeStart;
                   this.ping = ping;
                   this.pingStream.next(ping);
                });
          })

在我的 appcomponent 中,我有一个输入文本框,它具有 2way 绑定到 intvl = INTVL。 我真的不知道如何处理这个问题,因为 rxjs 有点难以入门,而且我也不是很有经验,所以非常感谢任何详细的帮助。

如果您需要更多信息,请告诉我。

编辑:第二种方法 - 我现在使用输入间隔在按钮单击时创建一个新流: pingservice.ts:

createNew(intvl: number) {
      this.pingStream = new Subject<number>();
      Observable.interval(intvl)
        .subscribe((data) => {
          let timeStart: number = performance.now();
          this._http.get(this.url)
            .subscribe((data) => {
              let timeEnd: number = performance.now();
              let ping: number = timeEnd - timeStart;
              this.ping = ping;
              this.pingStream.next(ping);
            });
        });
   }

app.component.ts:

newSubscription() {
      console.log(this.pingService.pingStream.isUnsubscribed);
      if (!this.pingService.pingStream.isUnsubscribed) {
         this.pingService.pingStream.unsubscribe();
      }
      if (this.pingService.pingStream.isUnsubscribed) {
         this.pingService.createNew(this.intvl)
         this.pingService.pingStream.subscribe(ping => {
            this.ping = ping;
            NTWDATA.datasets[0].data.pop();
            NTWDATA.datasets[0].data.splice(0, 0, this.ping);
         })
      }
   }

因此,停止 pingService 工作,新的 Stream 被创建并使用正确的间隔。现在我有另一个问题:在创建新的 pingStream 后订阅 pingStream 时,我还订阅了之前创建的所有其他 pingStream(或者至少我认为是这样),这会导致多个流传输我的数据。 5 次点击 = 5 次流。有没有办法“摧毁”这些流并在之后创建一个新的?

【问题讨论】:

  • 你看到that post了吗?
  • 是的,因为它在我的问题中已链接。
  • 好的。我想我知道问题是什么,但我希望能够在说些什么之前重现它。你能做个笨蛋吗?
  • 我不习惯 plunker,也不知道如何使用它。对不起。 :/ 但请随意说出您认为问题可能出在哪里!
  • 我没有使用过 ng2 并且不确定这是否符合您的需求,但是,这里有一个示例,使用选择框根据其更改事件更改间隔 jsbin.com/remifoxisu/1/edit?js,console,output

标签: angular rxjs observable


【解决方案1】:

一种方法是使用Subject 发出所需的间隔,然后使用 switchMap 和 flatMap 的组合。您可以通过取消订阅 interval$ 来暂停 ping。要恢复 ping 重新订阅并再次致电 setInterval。或者使用BehaviorSubject

interval$: Subject<number> = new Subject<number>();

constructor(){
  this.interval$
    .switchMap((int: number) => Observable  //switch to Observable with new interval
      .interval(int)
      .flatMap(() => StreamOfPings) //execute time measurement function
    )
    .subscribe(res => console.log(res));
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多