我正在使用最新的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')));
}
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
是的,总是退订。您有多种退订方式,如下所示:
正如许多人已经指出的那样,http返回一个Cold Observable,但是您仍然应该取消订阅该Observable。每次。
this.obs$.pipe(takeUntil(this.destroyed$)).subscribe(() => {
// some logic here
})
。我这样做的首选方式之一是利用avoid subscription leaks运算符。