Angular observables-如果没有订阅,我需要取消订阅吗?

问题描述 投票:3回答:6

我正在使用最新的angular 8,对可观察物的概念是新的。我有一个问题,如果我直接调用可观察对象而不将其应用于订阅变量,我是否仍需要取消订阅。以下是我想知道是否需要取消订阅的情况?提前非常感谢

方案1-从组件调用httpService:

Service - httpService

     getContactsHttp(){
         let headers: any = new HttpHeaders(this.authService.getHeadersClient());
         return this.httpClient.get('/contacts', {headers: headers})
          .pipe(timeout(this.authService.getTimeoutLimit('normal')));
        }

Component - Calling getContactsHttp and sorting response

getContacts() {
 this.httpService.getContactsHttp().subscribe((data:any[])=>{
  this.records = this.sortData(data)
 })
}

方案2-关于组件中可观察的对象

contacts$: new Subject<any[]>;

ngOnInit() {
  this.getContacts();
  this.contacts$.subscribe((data:any[])=>{
    this.records = this.sortData(data);
  })
}

getContacts() {
    this.httpService.getContactsHttp().subscribe((data:ContactSearch[])=>{      
      this.contacts$.next(data);
    })
  }

服务-httpService

     getContactsHttp(){
         let headers: any = new HttpHeaders(this.authService.getHeadersClient());
         return this.httpClient.get('/contacts', {headers: headers})
          .pipe(timeout(this.authService.getTimeoutLimit('normal')));
        }
angular rxjs observable
6个回答
1
投票

1)通常,直接拨打http呼叫时无需取消订阅。即使该组件被销毁,销毁后完成预订的开销也是微不足道的。如果要快速切换组件,则需要在此处退订。取消订阅也会取消http请求,因此,如果需要,请取消订阅。

取消订阅不会造成任何伤害。如果不确定,请始终退订。

2)当您订阅一本可观察到的东西时,您确实需要取消订阅。否则,这将导致内存(和性能)泄漏。因为可观察对象本身持有对该预订的引用,而该预订保留了对该组件的引用,所以该组件将永远不会从内存中清除,并且预订中描述的操作将一直运行,直到可观察对象完成为止(在您的情况下,它永远不会) 。对于组件的每个实例都会发生这种情况。

解决方案

我将分享两个常用的选项,以简化取消订阅的负担。扩展@ amanagg1204答案,您可以创建一个基础组件,并从中扩展所有将来的组件。您可以在其中包含一个自定义运算符。这样做有一个缺点-如果需要在组件中使用super.ngOnDestroy(),则必须始终调用ngOnDestroy

import { OnDestroy } from "@angular/core";
import { Subject, MonotypeOperatorFunction } from "rxjs";
import { takeUntil } from "rxjs/operators";

export abstract class UnsubscribeComponent implements OnDestroy {
  protected destroyed$: Subject<void> = new Subject();

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

  takeUntilDestroyed<T>(): MonotypeOperatorFunction<T> {
      return takeUntil(this.destroyed$);
  }
}

export class Component extends UnsubscribeComponent {
   ngOnInit() {
      this.contacts$.pipe(
              this.takeUntilDestroyed(),
          ).subscribe((data:any[])=>{
          this.records = this.sortData(data);
      });
   }

  // WARNING - if you declare your ngOnDestroy in the component
  ngOnDestroy() {
     // DO NOT FORGET to call this
     super.ngOnDestroy();
     doYourStuff();
  }

}

[其他选项(我更喜欢)是不具有父抽象类(尽管也可以这样实现),而是使用名为subsink的实用程序>

subsink

0
投票

是的,总是退订。您有多种退订方式,如下所示:


0
投票

正如许多人已经指出的那样,http返回一个Cold Observable,但是您仍然应该取消订阅该Observable。每次。


-1
投票
是的,取消订阅ngOnDestroy生命周期方法中的所有订阅是一种很好的做法,您可以通过在类级别变量中引用每个订阅的引用来进行订阅,然后手动取消订阅!

-1
投票
没有HttpClient返回一个冷可观察的对象,当第一个订阅者加入时触发一次,并在Web服务调用返回或出现错误时完成。

-1
投票
简短的回答,是的,您仍取消订阅组件中的可观察对象到this.obs$.pipe(takeUntil(this.destroyed$)).subscribe(() => { // some logic here }) 。我这样做的首选方式之一是利用avoid subscription leaks运算符。
© www.soinside.com 2019 - 2024. All rights reserved.