angular - Rxjs - 重新订阅取消订阅的 Observable

标签 angular typescript rxjs

我正在使用服务每 2.5 秒“ping”一次我的服务器,从我的服务器返回响应时间。因此我正在使用 observables。

我也在使用 angular 2 和 typescript。

我现在想在单击按钮时停止服务(取消订阅)。这很好用!该按钮应该是一个切换按钮,所以如果没有订阅,请订阅或其他方式。但是重新订阅不起作用!

这是我的服务:

export class PingService {
  pingStream: Subject<number> = new Subject<number>();
  ping: number = 0;
  url: string = url.href;

  constructor(private _http: Http) {
    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);
          });
      });
  }
}

这是我的点击功能:

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

我正在我的应用程序组件的构造函数中订阅 PingService。 数据显示在图表中。当我第一次单击该按钮时,它会停止服务,不再有数据更新。当我下次单击时,没有任何反应,尽管“this.pingService.pingStream.isUnsubscribed”返回 true。

我的构造函数:

    constructor(private location: Location,
       private pingService: PingService) {

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

当我第一次点击按钮时,我也收到错误“ObjectUnsubscribedError”。

感谢任何帮助!谢谢!

最佳答案

由于您使用的是 RxJS,因此您不必订阅/取消订阅。只需考虑使用 Rx 流的另一种方法。我们的想法是拥有 2 个流 maintoggle 流,因此只有当您的 toggle 流打开时它们才会触发事件。

var mainStream = Rx.Observable.interval(100).map(() => '.');

var display = document.getElementById('display');
var toggle = document.getElementById('toggle');

var toggleStream = Rx.Observable
  .fromEvent(toggle, 'change')
  .map(e => e.target.checked);

var resultStream = toggleStream
  .filter(x => x === true)
  .startWith(true)
  .flatMap(() => mainStream.takeUntil(toggleStream));

resultStream.subscribe(x => display.innerText += x);
<!DOCTYPE html>
<html>

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.min.js"></script>
  </head>

  <body>
    <input type="checkbox" id="toggle" checked> Check/uncheck to start/stop
    <div id="display"></div>
    
    <script src="script.js"></script>
  </body>

</html>

关于angular - Rxjs - 重新订阅取消订阅的 Observable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38950435/

相关文章:

Angular 10 : Property 'comments' does not exist on type 'typeof Dish'

javascript - Angular 绑定(bind)中的 Unicode 字符

Angular 2 : Use CanDeactivate, 但显示模式而不是 window.confirm

浏览器页面刷新期间 Angular 5 Ngrx 状态丢失

javascript - 由于错误,无法使用 Angular FormsModule

ios - 从照片库中选择视频时,仅适用于 iOS 13.2 上 Ionic 中的视频的文件大小为 0

javascript - 在 TypeScript 中获取 jQuery 插件到 "see"jQuery

angular - 如果您还使用 children 参数,请使用 redirectTo,这可能吗?

angular - getter 和 setter 中 Observable 的 Typescript 返回类型

websocket - Angular2 dart ngFor 使用 WebSocket 时不更新 View