可观察的角度-如果没有订阅,我需要取消订阅吗? [英] Angular observables - Do I need unsubscribe if no subscription?

查看:63
本文介绍了可观察的角度-如果没有订阅,我需要取消订阅吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using latest angular 8 and am new to the concept of observables. Question I have if I am directly calling an observable and not apply it to a subscription variable, do I still need to unsubscribe. Below are the scenarios I would like to know if I need to unsubscribe on? Many thanks in advance

方案1-从组件调用httpService:

Scenario 1 - Calling a httpService from a component:

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-组件中的可观察物

Scenario 2 - on an observable susbcribed in a component

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

Service - httpService

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

推荐答案

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

1) Generally, you don't need to unsubscribe when calling an http call directly. Even if the component get's destroyed, the overhead with the subscription finishing after the destruction is insignificant. You'd need to unsubscribe here if switching your components rapidly. Also unsubscribing cancels the http request, so if that's desired, then unsubscribe.

退订不会造成任何伤害.如果不确定,请务必退订.

Unsubscribing does not do any harm. If you're not sure, always unsubscribe.

2)当您订购一个可观察物时,您确实需要退订该可观察物,该可观察物在您的杂物销毁后还没有完成.否则,这将导致内存(和性能)泄漏.由于可观察对象本身持有对该预订的引用,而该预订保留了对该组件的引用,因此该组件将永远不会从内存中清除,并且预订中描述的操作将一直运行,直到可观察对象完成为止(在您的情况下,这永远不会发生) .对于组件的每个实例都会发生这种情况.

2) You do need to unsubscribe when subscribing to an observable that does not complete when your compoment gets destroyed. Otherwise this would cause a memory (and performance) leak. Because the observable itself holds a reference to the subscription and the subscription holds the reference to the component, the component will never get cleared from the memory and the action described in the subscription will be running until the observable completes, which in your case is never. That will happend for every instance of your component.

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

I'll share two popular options on simplifying the burden of unsubscribing. Expanding on the @amanagg1204 answer, you could create a base component from which you'd extend all of your future components. You can have a custom operator in it. There is one downside to that - you always have to call super.ngOnDestroy() if you need to use ngOnDestroy in your component.

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();
  }

}

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

Other option (my prefered) is not to have a parent abstract class (although it could also be implemented like that), but to use an utility called subsink (npm i subsink --save)

import { SubSink } from 'subsink';

export class SampleComponent implements OnInit, OnDestroy {
  private subs = new SubSink();

  ngOnInit(): void {
    // Just put it into sink.
    this.subs.sink = this.contacts$.subscribe((data:any[])=>{
      this.records = this.sortData(data);
    });
    // call repeatedly
    this.subs.sink = this.otherService$.subscribe((data:any[])=>{
      this.things = this.sortData(data);
    });
  }

  ngOnDestroy(): void {
    // this will unsubscribe all
    this.subs.unsubscribe();
  }
}

这篇关于可观察的角度-如果没有订阅,我需要取消订阅吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆