如何正确取消订阅Observable Angular 7?

时间:2019-01-14 10:54:35

标签: angular memory-leaks

我目前正在确保我的应用程序没有内存泄漏。我正在关注this教程,他将向您展示如何从使用subscribe()变为async,以及如何在ngOnDestroy期间明确退订。

我正在努力测试我的实施是否有效,我想知道我在我的项目中对它的实施是否实际上正在取消订阅。

以下是本教程中其组件的内容:

@Component({
  /* ... */
  template: `
    <ul *ngIf="todos.length > 0">
      <li *ngFor="let todo of todos">{{todo.name}}</li>
    </ul>   
  `
})
export class TodosComponent implements OnInit, OnDestroy {
  private unsubscribe$ = new Subject<void>();

  todos: Todo[];

  constructor(private store: Store<State>) {}

  ngOnInit() {
    this.store
      .pipe(select(selectTodos), takeUntil(this.unsubscribe$)) // unsubscribe to prevent memory leak
      .subscribe(todos => this.todos = todos);            // unwrap observable
  }

  ngOnDestroy(): void {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }
}

我的ngOnDestroy看起来和他的完全一样,但这就是我对该服务的调用:

this.insightsService.getLatestsInsights(5)
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(z => {
        if (z != null) {
          this.latestInsights = z;
          this.visibleSlides = z.slice(0, this.amountOfSlidesToShow);
        }
      })

因此该服务有效,但是我只想知道我的实现是否正确?不确定选择功能是什么还是仅适用于他使用的功能。让我知道我是否可以提供信息。

2 个答案:

答案 0 :(得分:0)

在教程中,他正在使用Rgrx商店。该存储可以多次产生值。因此,这不是一次性的事情。出于同样的原因,必须退订Observable

在您的示例中,您正在调用insightsService.getLatestsInsights(5),该返回的是Observable。但是我认为这只是一次性的事情,就像您的getLatestsInsights中一样,很可能您要返回的ObservableHttpClient中的一种方法返回。这些方法通常返回仅产生一次值并完成的Observables。 我只是在这里假设。如果我错了,请纠正我。

因此,如果确实是这样,那么您实际上并不需要首先从unsubscribeSubscription,更不用说正确地考虑了。

  

您可以在RxJS: Don’t Unsubscribe的Rxjs主管Ben Lesh的文章{{3}}上unsubscribe上详细了解。

答案 1 :(得分:0)

这很有趣,但是我找不到这个问题的完整答案,我找到了三种方法,但是我不确定它们是否绝对正确,所以如果有人知道更好的解决方案,请提供。 !!!未检查下面的重要语法

  
      
  1. 第一个解决方案是为变量分配订阅,然后将其用于取消订阅。
  2.   
[3,4]
  
      
  1. 第二个解决方案是使用RxJs的Subscription类。可以将所有订阅放在一起,以便对一个订阅的unsubscribe()的调用可以取消订阅多个订阅。我们可以通过将一个订阅“添加”到另一个订阅中来实现此行为:
  2.   
public mySubscription: Observable<Array<Something>>;

export class someComponent OnInit, OnDestroy {


  constructor(private myService: MyService) {}

  ngOnInit() {

      this.mySubscription = this.myService.someMethod().subscribe(response => ... do something);
  }

  ngOnDestroy() {
     this.mySubscription.unsubscribe();
  }

.....
  
      
  1. 第三个也是最后一个解决方案是使用rxjs的takeUntil运算符
  2.   
....

import { Subscription } from 'rxjs/Subscription';

....

private subscription = new Subscription();

public mySubscription1: Observable<Array<Something>>;
public mySubscription2: Observable<Array<Something>>;

export class someComponent OnInit, OnDestroy {


    constructor(private myService: MyService) { }

    ngOnInit() {

        this.mySubscription1 = this.myService.someMethod().subscribe(response => ... do something);
        this.subscription.add(this.subscription.add(this.mySubscription1));

        this.mySubscription2 = this.myService.someMethod().subscribe(response => ... do something);
        this.subscription.add(this.subscription.add(this.mySubscription1));
    }

    ngOnDestroy() {

        if (this.subscription) {
            this.subscription.unsubscribe();
        }
    }

.....