Angular订阅/取消订阅最佳实践

时间:2017-11-07 08:04:15

标签: angular typescript

我目前想知道角度订阅和取消订阅。关于这个问题有很多东西,所以我在这一切中都有点迷失。

我应该何时取消订阅?如果我不退订,会发生什么?我从来没有遇到过reliquat订阅的任何错误。

有没有办法自动取消订阅组件/应用程序中的所有内容,这样我就不必通过订阅声明1个属性?这可能非常烦人:

@Component({
  selector: 'subscriptionTest',
  template: `...`,
})
export class SubTestComponent {
  first;
  second;
  third;

  constructor(private remote: RemoteService){}

  ngOnInit() {
    this.first = remote.getSomeData().subscribe(data => // do something);
    this.second = Observable.interval(500).subscribe(event => // do something);
    this.third = remote.getSomeOtherData().subscribe(data => // do something);

  }

  ngOnDestroy() {
    this.first.unsubscribe();
    this.second.unsubscribe();
    this.third.unsubscribe();
  }

}

4 个答案:

答案 0 :(得分:2)

takeUntil运算符是一种“自动”取消订阅任何订阅的简单方法,例如:

@Component({...})
export class AppComponent implements OnInit, OnDestroy {
  destroy$: Subject<boolean> = new Subject<boolean>();

  constructor(private apollo: Apollo) {
  }

  ngOnInit() {
    this.apollo.watchQuery({
        query: gql`
        query getAllPosts {
          allPosts {
            title
            description
            publishedAt
          }
        }
      `
      })
      .takeUntil(this.destroy$)
      .subscribe(({data}) => {
        console.log(data);
      });
      remote.getSomeData().subscribe(data => // do something);
      Observable.interval(500).subscribe(event => // do something);
      remote.getSomeOtherData().subscribe(data => // do something);
  }

  onStartInterval() {
    Observable
      .interval(250)
      .takeUntil(this.destroy$)
      .subscribe(val => {
        console.log('Current value:', val);
      });
  }

  ngOnDestroy() {
    this.destroy$.next(true);
    // Now let's also unsubscribe from the subject itself:
    this.destroy$.unsubscribe();
  }
}

您不必声明每个订阅,只需在每个订阅上添加.takeUntil(this.destroy$)运算符

来源:https://alligator.io/angular/takeuntil-rxjs-unsubscribe/

关于订阅的精彩帖子:Angular/RxJs When should I unsubscribe from `Subscription`

答案 1 :(得分:1)

如果你不想重复自己,请使用超级课程:

/**
*  Unsubscribe from any Observable using takeUntil and this.destroy$
*      someObservable.pipe( // lettable operators in rxjs ^5.5.0
*          ...
*          takeUntil(destroy$)
*      )
*      .subscribe(....
**/
export class Destroyer implements OnDestroy {
    destroy$: Subject<boolean> = new Subject<boolean>();

    ngOnDestroy() {
        // Unsubscribe from whatever used takeUntil(destroy$)
        this.destroy$.next(true);
        // Now let's also unsubscribe from the subject itself:
        this.destroy$.unsubscribe();
    }
}

随处使用:

export class SomeComponent extends Destroyer{

   constructor(private remote: RemoteService){
       super();
   }

   ngOnInit() {
        remote.getSomeData()
              .pipe(takeUntil(this.destroy$)) 
              //.takeUntil(this.destroy$) // before rxjs ^5.5.0
              .subscribe(data => {/* do something*/});

        Observable.interval(500)
              .pipe(takeUntil(this.destroy$))
              //.takeUntil(this.destroy$) // before rxjs ^5.5.0
              .subscribe(data => {/* do something*/});
      }
   }

   // optional. You don't need ngOnDestroy everywhere.
   ngOnDestroy(): void {

       // Let Destroyer trigger unsubscribe
       super.ngOnDestroy();

       // ...SomeComponent other cleanup.
   }


}

答案 2 :(得分:0)

您可以使用第三方插件,例如ngx-auto-unsubscribe

答案 3 :(得分:0)

最好的方法是使用Subscription类。

为此,您将在组件中创建一个变量,如下所示……

private subs: Subscription = Subscription.EMPTY;

然后像这样使用...

this.subs.add(this.route.data.subscribe(...

this.subs.add(this.clientService.login(this.username, this.password).subscribe(...

然后在您的ngOnDestroy()中进行唯一调用,例如

this.subs.unsubscribe();