简体   繁体   中英

Best practices for avoiding memory leaks in angular

I'm trying detect and fix potential memory leaks in my angular/spartacus application. So basically I'm looking for any "subscribe(..." calls in my code base and evaluate what I can do.

I know that simplest form is simply to use observables directly in html and read them by using the async-pipe instead of calling the subscribe method and assigning the value to a component-class-attribute. But sometimes it's not that simple. Sometimes the data for the observable has to be prepared somehow.

My question is if these approaches are just as valid?

  1. Is it a good Idea to assign ANY "subscribe()" call to a Subscription object, which I will eventually unsubscribe from in an "ngOnDestroy"-method

  2. Why can't I instead of using a Subscription object call instead the "unsubscribe"-method right after the "subscribe" call?

  3. MOST IMPORTANT: Is there any benefit in using the "pipe()" operator, to receive data, manipulate it with SwitchMap and then return it to the "obs$"-object, that I can read in html via async pipe. Are there any hidden Subscriptions tied to a "pipe(...)"-process that I have to manually unsubscribe from, or is it indeed always the preferable approach compared to explicitly subscribing and then assigning the observed object to a component-class-attribute?

Example: instead of this

  mergedReferences$: Observable<Observable<Product>[]>;
  subscription = new Subscription();

  ngOnInit() {

    this.subscription.add(this.cart$.subscribe(c => {
      if (c.code) {
        this.mergedReferences$ = this.getMergedProducts(c.code);
      }
    }));

  }
  ngOnDestroy(): void {
    this.subscription?.unsubscribe();
  }

doing simply this

  mergedReferences$: Observable<Observable<Product>[]>;


  ngOnInit() {

    this.mergedReferences$ = this.cart$.pipe(switchMap((c: Cart) => this.getMergedProducts(c.code!)))
  }

another option you can do is you can use the pipe(take(1)) operator before any subscribe(). this is will close the subscription after taking 1 value. So somehting like this:

this.cart$.pipe(take(1)).subscribe(c => {
  if (c.code) {
    this.mergedReferences$ = this.getMergedProducts(c.code);
  }
}));

But your 1st approach is also a valid way of handling the subscription. You are correctly unsubscribing in the ngOnDestroy block. Both ways are valid and are probably only a matter of preference

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM