Rxjs Observable Lifecycle

微笑、不失礼 提交于 2019-12-23 02:32:42

问题


If I am ever working with rxjs, I normally, in my component file, keep track of all of my subscriptions by pushing said subscriptions into a Subscription array:

private subcriptions: Subscription[];

this.subscriptions.push(this.myObservableOne.subscribe(...));
this.subscriptions.push(this.myObservableTwo.subscribe(...));

public ngOnDestroy(): void {
    this.subscriptions.forEach(s => s.unsubscribe());
}

Now, I am running into something that I thought was interesting. If I instead need to subscribe to an Observable from a service:

this.myService.myObservable.subscribe(...)

Who owns the subscription? Will my component own it, or will the service own it? In other words, will my service need to implement ngOnDestroy to unsubscribe from that Observable?

I feel like doing: this.subscriptions.push(this.myService.myObservable.subscribe(...)); might work but I am not entirely sure.


回答1:


Calling .subscribe(...) on an Observable returns a Subscription.

If you don't assign this subscription to a variable (or in your case push it to an array of subscriptions), you will lose reference to this subscription, hence you can't unsubscribe from it, which can cause memory leaks.

So your assumption of pushing it into array of subscriptions:

this.subscriptions.push(this.myService.myObservable.subscribe(...));

and unsubscribing in ngOnDestroy of your component is correct.




回答2:


Another option is to use takeWhile or something similar with a flag such as the componentActive flag below. Something like the code shown below.

This completes the subscription so you don't need to unsubscribe.

import { Component, OnInit, OnDestroy } from '@angular/core';

import { Product } from '../product';

import { Observable } from 'rxjs';
import { takeWhile } from 'rxjs/operators';

/* NgRx */
import { Store, select } from '@ngrx/store';

@Component({
  selector: 'pm-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit, OnDestroy {
  componentActive = true;

  // Used to highlight the selected product in the list
  selectedProduct: Product | null;

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

  ngOnInit(): void {

    // Subscribe here because it does not use an async pipe
    this.store.pipe(
      select(fromProduct.getCurrentProduct),
      takeWhile(() => this.componentActive)
    ).subscribe(
      currentProduct => this.selectedProduct = currentProduct
    );

  }

  ngOnDestroy(): void {
    this.componentActive = false;
  }

}


来源:https://stackoverflow.com/questions/51504809/rxjs-observable-lifecycle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!