【问题标题】:How can I subscribe and unsubscribe from an observable?如何订阅和取消订阅 observable?
【发布时间】:2019-05-27 13:07:24
【问题描述】:

我有两个函数,我需要在第一个函数中订阅 observable,在第二个函数中取消订阅。但在我的代码中,我无法从第二个函数访问 observable,因为它不在其范围内。

这是我的功能:

 start() {
    this.max = this.duration;
    const interval = Observable.interval(this.selectedSprint.duration);
    interval
      .takeWhile(_ => !this.isFinished)
      .do(i => this.current += 1)
      .subscribe();
    }

    stop() {
    // here I need to unsybscribe to the observable
    this.dialogService.openConfirmDialog('do you want to stop ?')
      .afterClosed().subscribe((result: boolean) => {
        if (result) {
    // if true logic
        }
      });
      }

【问题讨论】:

    标签: angular rxjs angular2-observables


    【解决方案1】:

    一种解决方案是将订阅存储在您的组件中。

    export class Component {
      interval$: Subscription;
    
      start() {
        this.max = this.duration;
        this.interval$ = Observable.interval(this.selectedSprint.duration)
          .takeWhile(_ => !this.isFinished)
          .do(i => this.current += 1)
          .subscribe();
      }
    
      stop() {
        // here I need to unsybscribe to the observable
        this.dialogService.openConfirmDialog('do you want to stop ?')
          .afterClosed().subscribe((result: boolean) => {
            if (result) {
              this.interval$.unsubscribe();
            }
        });
      }
    }
    

    编辑以回答 OP 的评论

    export class Component {
      intervalSub$: Subscription;
      intervalObs: Observable<number>;
    
      start() {
        this.max = this.duration;
        this.intervalObs$ = Observable.interval(this.selectedSprint.duration)
          .takeWhile(_ => !this.isFinished)
          .do(i => this.current += 1);
       this.intervalSub$ = intervalObs.subscribe();
      }
    
      stop() {
        // here I need to unsybscribe to the observable
        this.dialogService.openConfirmDialog('do you want to stop ?')
          .afterClosed().subscribe((result: boolean) => {
            if (result) {
              this.intervalSub$.unsubscribe();
            }
        });
      }
      /**
       * If you unsubscribed from the interval and you want to resume
       * (If this.isFinished is true, it won't do a thing)
       */
      resume() {
        this.intervalObs.subscribe();
      }
    }
    

    【讨论】:

    • 我试过这个解决方案,但我一直得到这个:类型'Observable'缺少来自类型'订阅'的以下属性:关闭、添加、删除、取消订阅 ts(2739)
    • 您必须在 do() 之后分配了您的 interval$ 字段,这是一个 Observable。为了能够取消订阅,您需要将subscribe() 的结果分配给该字段。
    • 只有一个问题,退订后可以再订阅吗?如果(!结果)
    • 是的,但要做到这一点,您需要存储订阅和 observable => 您可以订阅 observable 并取消订阅。
    • 好的,谢谢,你能给我举个例子吗?
    【解决方案2】:

    使用this.sub = interval.[...].subscribe() 在您的班级中保存对您订阅的引用。

    这样,您就可以在第二个函数中调用this.sub.unsubscribe()

    【讨论】:

      【解决方案3】:

      如果您在班级中,则可以将调用 .subscribe() 返回的 subscription 对象保留为属性。

      start() {
         this.max = this.duration;
         const interval = Observable.interval(this.selectedSprint.duration);
         interval
           .takeWhile(_ => !this.isFinished)
           .do(i => this.current += 1);
         this.intervalSubscription = interval.subscribe();
      }
      

      这将允许您在 stop 方法中取消订阅

      stop() {
          this.intervalSubscription.unsubscribe(...);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-19
        • 2020-08-29
        • 1970-01-01
        • 2016-12-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多