Angular/RxJs When should I unsubscribe from `Subscription`
我何时应该存储
保存所有订阅会在组件代码中引入很多混乱。
HTTP客户端指南忽略这样的订阅:
1 2 3 4 5 6 | getHeroes() { this.heroService.getHeroes() .subscribe( heroes => this.heroes = heroes, error => this.errorMessage = error); } |
同时路线& 导航指南说:
Eventually, we'll navigate somewhere else. The router will remove this component from the DOM and destroy it. We need to clean up after ourselves before that happens. Specifically, we must unsubscribe before Angular destroys the component. Failure to do so could create a memory leak.
We unsubscribe from our
Observable in thengOnDestroy method.
1 2 3 4 5 6 7 8 9 10 11 12 | private sub: any; ngOnInit() { this.sub = this.route.params.subscribe(params => { let id = +params['id']; // (+) converts string 'id' to a number this.service.getHero(id).then(hero => this.hero = hero); }); } ngOnDestroy() { this.sub.unsubscribe(); } |
---编辑4 - 其他资源(2018/09/01)
最近在Angular Ben Lesh和Ward Bell的一集中讨论了如何/何时取消订阅组件的问题。讨论从大约1:05:30开始。
沃德提到
作为回应,Ben提到现在正在进行讨论以允许Obse??rvables挂钩Angular组件生命周期事件,而Ward建议生命周期事件的Observable,组件可以订阅它作为一种知道何时完成作为组件内部状态维护的Observable的方式。
也就是说,我们现在大多需要解决方案,所以这里有一些其他资源。
来自RxJs核心团队成员Nicholas Jamieson的
轻量级npm包,公开一个Observable操作符,该操作符将一个组件实例(
https://github.com/NetanelBasal/ngx-take-until-destroy
如果你没有进行AOT构建,那么上面的另一种变化与人体工程学稍好一些(但我们现在都应该做AOT)。
https://github.com/smnbbrv/ngx-rx-collector
自定义指令
https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697f
我在对Nicholas博客的评论中提到过度使用
---编辑3 - '官方'解决方案(2017/04/09)
我在NGConf与Ward Bell谈到了这个问题(我甚至向他展示了这个答案,他说这是正确的)但是他告诉我Angular的文档团队解决了这个未发表的问题(尽管他们正在努力让它获得批准) )。他还告诉我,我可以用即将推出的官方建议更新我的答案。
我们今后应该使用的解决方案是向所有在类代码中
然后我们在
秘密酱(正如@metamaker已经指出的那样)是在每个
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import { Component, OnDestroy, OnInit } from '@angular/core'; // RxJs 6.x+ import paths import { filter, startWith, takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; import { BookService } from '../books.service'; @Component({ selector: 'app-books', templateUrl: './books.component.html' }) export class BooksComponent implements OnDestroy, OnInit { private ngUnsubscribe = new Subject(); constructor(private booksService: BookService) { } ngOnInit() { this.booksService.getBooks() .pipe( startWith([]), filter(books => books.length > 0), takeUntil(this.ngUnsubscribe) ) .subscribe(books => console.log(books)); this.booksService.getArchivedBooks() .pipe(takeUntil(this.ngUnsubscribe)) .subscribe(archivedBooks => console.log(archivedBooks)); } ngOnDestroy() { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); } } |
注意:将
---编辑2(2016/12/28)
来源5
Angular教程,路由章节现在陈述如下:"路由器管理它提供的可观察量并本地化订阅。订阅在组件被销毁时被清除,防止内存泄漏,所以我们不需要取消订阅路线可以观察到。" - Mark Rajcok
这里讨论了关于路由器可观测量的Angular文档的Github问题,其中Ward Bell提到所有这些的澄清正在进行中。
---编辑1
来源4
在来自NgEurope的视频中,Rob Wormald还表示您不需要取消订阅Router Observables。他还在2016年11月的视频中提到了
---原始答案
TLDR:
对于这个问题,有(2)种
如果手动调用
不要担心有限的,
来源1
我在这里找到了Angular Gitter的Rob Wormald的回答。
他说(我为了清晰而重组,重点是我的)
if its a single-value-sequence (like an http request)
the manual cleanup is unnecessary (assuming you subscribe in the controller manually)Ok.
i should say"if its a sequence that completes" (of which single value sequences, a la http, are one)
Ok.
if its an infinite sequence, you should unsubscribe which the async pipe does for you
Ok.
另外他在这个关于Observables的youtube视频中提到了
来源2
同样在Angular 2的Rangle指南中,它会读取
In most cases we will not need to explicitly call the unsubscribe method unless we want to cancel early or our Observable has a longer lifespan than our subscription. The default behavior of Observable operators is to dispose of the subscription as soon as .complete() or .error() messages are published. Keep in mind that RxJS was designed to be used in a"fire and forget" fashion most of the time.
Ok.
什么时候短语
它适用于在
如果我们订阅了一个
当请求返回或最终发出第10个值时,
来源3
如果我们从同一个Rangle指南中查看这个例子,我们可以看到
可以通过导航来销毁该组件,在这种情况下,路由参数可能仍会改变(它们可能在技术上改变直到应用程序结束)并且仍然会分配订阅中分配的资源,因为没有
好。
您不需要手动拥有大量订阅和取消订阅。使用RxJS.Subject和takeUntil组合来处理像boss这样的订阅:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import {Subject} from"rxjs/Subject"; @Component( { moduleId: __moduleName, selector: 'my-view', templateUrl: '../views/view-route.view.html', } ) export class ViewRouteComponent implements OnDestroy { componentDestroyed$: Subject<boolean> = new Subject(); constructor(protected titleService: TitleService) { this.titleService.emitter1$ .takeUntil(this.componentDestroyed$) .subscribe( (data: any) => { // ... do something 1 } ); this.titleService.emitter2$ .takeUntil(this.componentDestroyed$) .subscribe( (data: any) => { // ... do something 2 } ); // ... this.titleService.emitterN$ .takeUntil(this.componentDestroyed$) .subscribe( (data: any) => { // ... do something N } ); } ngOnDestroy() { this.componentDestroyed$.next(true); this.componentDestroyed$.complete(); } } |
@acumartini在评论中提出的替代方法使用takeWhile而不是takeUntil。您可能更喜欢它,但请注意,这样您的Observable执行将不会在组件的ngDestroy上被取消(例如,当您耗费时间计算或等待来自服务器的数据时)。基于takeUntil的方法没有这个缺点,导致立即取消请求。感谢@AlexChe在评论中的详细解释。
所以这是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | @Component( { moduleId: __moduleName, selector: 'my-view', templateUrl: '../views/view-route.view.html', } ) export class ViewRouteComponent implements OnDestroy { alive: boolean = true; constructor(protected titleService: TitleService) { this.titleService.emitter1$ .takeWhile(() => this.alive) .subscribe( (data: any) => { // ... do something 1 } ); this.titleService.emitter2$ .takeWhile(() => this.alive) .subscribe( (data: any) => { // ... do something 2 } ); // ... this.titleService.emitterN$ .takeWhile(() => this.alive) .subscribe( (data: any) => { // ... do something N } ); } // Probably, this.alive = false MAY not be required here, because // if this.alive === undefined, takeWhile will stop. I // will check it as soon, as I have time. ngOnDestroy() { this.alive = false; } } |
Subscription类有一个有趣的特性:
Represents a disposable resource, such as the execution of an Observable. A Subscription has one important method, unsubscribe, that takes no argument and just disposes the resource held by the subscription.
Additionally, subscriptions may be grouped together through the add() method, which will attach a child Subscription to the current Subscription. When a Subscription is unsubscribed, all its children (and its grandchildren) will be unsubscribed as well.
您可以创建一个聚合订阅对象,该对象将您的所有订阅分组。
您可以通过创建一个空的Subscription并使用其
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @Component({ ... }) export class SmartComponent implements OnInit, OnDestroy { private subscriptions = new Subscription(); constructor(private heroService: HeroService) { } ngOnInit() { this.subscriptions.add(this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes)); this.subscriptions.add(/* another subscription */); this.subscriptions.add(/* and another subscription */); this.subscriptions.add(/* and so on */); } ngOnDestroy() { this.subscriptions.unsubscribe(); } } |
关于Angular组件内可观察的取消订阅的一些最佳实践:
来自
When subscribing to an observable in a component, you almost always arrange to unsubscribe when the component is destroyed.
Ok.
There are a few exceptional observables where this is not necessary. The ActivatedRoute observables are among the exceptions.
Ok.
The ActivatedRoute and its observables are insulated from the Router itself. The Router destroys a routed component when it is no longer needed and the injected ActivatedRoute dies with it.
Ok.
Feel free to unsubscribe anyway. It is harmless and never a bad practice.
Ok.
并在回应以下链接:
我收集了一些关于Angular组件中可观察的取消订阅的最佳实践,以便与您分享:
注意:关于作用域服务,即组件提供程序,它们在销毁组件时被销毁。在这种情况下,如果我们订阅了这个提供程序中的任何observable,我们应该考虑使用
一个不错的最终提示:如果您不知道是否正在自动取消订阅/完成一个observable,请将
好。
这取决于。如果通过调用
让我们仔细看看你的例子:
1 2 | _xhr.addEventListener('load', onLoad); _xhr.addEventListener('error', onError); |
通过调用
1 2 3 | _xhr.removeEventListener('load', onLoad); _xhr.removeEventListener('error', onError); _xhr.abort(); |
请注意,
通常,这足以保证手动
至于你的第二个例子,它取决于
你的问题的底线是始终将
如有疑问,请查看该可观察的实现。如果observable在其
Angular 2官方文档提供了何时取消订阅以及何时可以安全忽略的说明。看看这个链接:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
查找标题为Parent的段落,子项通过服务进行通信,然后是蓝色框:
Notice that we capture the subscription and unsubscribe when the AstronautComponent is destroyed. This is a memory-leak guard step. There is no actual risk in this app because the lifetime of a AstronautComponent is the same as the lifetime of the app itself. That would not always be true in a more complex application.
We do not add this guard to the MissionControlComponent because, as the parent, it controls the lifetime of the MissionService.
我希望这可以帮助你。
基于:使用Class继承挂钩到Angular 2组件生命周期
另一种通用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | export abstract class UnsubscribeOnDestroy implements OnDestroy { protected d$: Subject; constructor() { this.d$ = new Subject<void>(); const f = this.ngOnDestroy; this.ngOnDestroy = () => { f(); this.d$.next(); this.d$.complete(); }; } public ngOnDestroy() { // no-op } } |
并使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Component({ selector: 'my-comp', template: `` }) export class RsvpFormSaveComponent extends UnsubscribeOnDestroy implements OnInit { constructor() { super(); } ngOnInit(): void { Observable.of('bla') .takeUntil(this.d$) .subscribe(val => console.log(val)); } } |
由于seangwright的解决方案(编辑3)似乎非常有用,我还发现将此功能打包到基本组件中很麻烦,并且暗示其他项目团队成员记得在ngOnDestroy上调用super()来激活此功能。
这个答案提供了一种从超级调用中解脱出来的方法,并使"co??mponentDestroyed $"成为基本组件的核心。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class BaseClass { protected componentDestroyed$: Subject<void> = new Subject<void>(); constructor() { /// wrap the ngOnDestroy to be an Observable. and set free from calling super() on ngOnDestroy. let _$ = this.ngOnDestroy; this.ngOnDestroy = () => { this.componentDestroyed$.next(); this.componentDestroyed$.complete(); _$(); } } /// placeholder of ngOnDestroy. no need to do super() call of extended class. ngOnDestroy() {} } |
然后您可以自由使用此功能,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Component({ selector: 'my-thing', templateUrl: './my-thing.component.html' }) export class MyThingComponent extends BaseClass implements OnInit, OnDestroy { constructor( private myThingService: MyThingService, ) { super(); } ngOnInit() { this.myThingService.getThings() .takeUntil(this.componentDestroyed$) .subscribe(things => console.log(things)); } /// optional. not a requirement to implement OnDestroy ngOnDestroy() { console.log('everything works as intended with or without super call'); } } |
官方编辑#3答案(和变体)运作良好,但让我感觉到的是围绕可观察订阅的业务逻辑的"混乱"。
这是使用包装器的另一种方法。
Warining: experimental code
文件subscribeAndGuard.ts用于创建一个新的Observable扩展来包装
用法与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import { Observable } from 'rxjs/Observable'; import { Subscription } from 'rxjs/Subscription'; const subscribeAndGuard = function(component, fnData, fnError = null, fnComplete = null) { // Define the subscription const sub: Subscription = this.subscribe(fnData, fnError, fnComplete); // Wrap component's onDestroy if (!component.ngOnDestroy) { throw new Error('To use subscribeAndGuard, the component must implement ngOnDestroy'); } const saved_OnDestroy = component.ngOnDestroy; component.ngOnDestroy = () => { console.log('subscribeAndGuard.onDestroy'); sub.unsubscribe(); // Note: need to put original back in place // otherwise 'this' is undefined in component.ngOnDestroy component.ngOnDestroy = saved_OnDestroy; component.ngOnDestroy(); }; return sub; }; // Create an Observable extension Observable.prototype.subscribeAndGuard = subscribeAndGuard; // Ref: https://www.typescriptlang.org/docs/handbook/declaration-merging.html declare module 'rxjs/Observable' { interface Observable< T > { subscribeAndGuard: typeof subscribeAndGuard; } } |
这是一个包含两个订阅的组件,一个包含包装,另一个包含。唯一需要注意的是它必须实现OnDestroy(如果需要,还有空体),否则Angular不知道调用包装版本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import { Component, OnInit, OnDestroy } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import 'rxjs/Rx'; import './subscribeAndGuard'; @Component({ selector: 'app-subscribing', template: 'Subscribing component is active', }) export class SubscribingComponent implements OnInit, OnDestroy { ngOnInit() { // This subscription will be terminated after onDestroy Observable.interval(1000) .subscribeAndGuard(this, (data) => { console.log('Guarded:', data); }, (error) => { }, (/*completed*/) => { } ); // This subscription will continue after onDestroy Observable.interval(1000) .subscribe( (data) => { console.log('Unguarded:', data); }, (error) => { }, (/*completed*/) => { } ); } ngOnDestroy() { console.log('SubscribingComponent.OnDestroy'); } } |
这里有一个演示插件
另外一点:
重新编辑3 -"官方"解决方案,这可以通过在订阅之前使用takeWhile()而不是takeUntil()来简化,并且在ngOnDestroy中使用简单的布尔值而不是另一个Observable。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Component({...}) export class SubscribingComponent implements OnInit, OnDestroy { iAmAlive = true; ngOnInit() { Observable.interval(1000) .takeWhile(() => { return this.iAmAlive; }) .subscribe((data) => { console.log(data); }); } ngOnDestroy() { this.iAmAlive = false; } } |
在@seangwright的回答之后,我编写了一个抽象类来处理组件中的"无限"observables订阅:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | import { OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; import { Subject } from 'rxjs/Subject'; import { Observable } from 'rxjs/Observable'; import { PartialObserver } from 'rxjs/Observer'; export abstract class InfiniteSubscriberComponent implements OnDestroy { private onDestroySource: Subject = new Subject(); constructor() {} subscribe(observable: Observable): Subscription; subscribe( observable: Observable, observer: PartialObserver ): Subscription; subscribe( observable: Observable, next?: (value: any) => void, error?: (error: any) => void, complete?: () => void ): Subscription; subscribe(observable: Observable, ...subscribeArgs): Subscription { return observable .takeUntil(this.onDestroySource) .subscribe(...subscribeArgs); } ngOnDestroy() { this.onDestroySource.next(); this.onDestroySource.complete(); } } |
要使用它,只需在角度组件中扩展它并按如下方式调用
1 | this.subscribe(someObservable, data => doSomething()); |
它也像往常一样接受错误和完整的回调,一个观察者对象,或者根本不接受回调。如果您还在子组件中实现该方法,请记得调用
在这里找到Ben Lesh的另外一个参考:RxJS:不要取消订阅。
我试过seangwright的解决方案(编辑3)
这不适用于由计时器或间隔创建的Observable。
但是,我通过使用另一种方法使其工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import { Component, OnDestroy, OnInit } from '@angular/core'; import 'rxjs/add/operator/takeUntil'; import { Subject } from 'rxjs/Subject'; import { Subscription } from 'rxjs/Subscription'; import 'rxjs/Rx'; import { MyThingService } from '../my-thing.service'; @Component({ selector: 'my-thing', templateUrl: './my-thing.component.html' }) export class MyThingComponent implements OnDestroy, OnInit { private subscriptions: Array<Subscription> = []; constructor( private myThingService: MyThingService, ) { } ngOnInit() { const newSubs = this.myThingService.getThings() .subscribe(things => console.log(things)); this.subscriptions.push(newSubs); } ngOnDestroy() { for (const subs of this.subscriptions) { subs.unsubscribe(); } } } |
我喜欢最后两个答案,但如果子类在
我修改它是这样,看起来它解决了这个问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | export abstract class BaseComponent implements OnDestroy { protected componentDestroyed$: Subject<boolean>; constructor() { this.componentDestroyed$ = new Subject<boolean>(); let f = this.ngOnDestroy; this.ngOnDestroy = function() { // without this I was getting an error if the subclass had // this.blah() in ngOnDestroy f.bind(this)(); this.componentDestroyed$.next(true); this.componentDestroyed$.complete(); }; } /// placeholder of ngOnDestroy. no need to do super() call of extended class. ngOnDestroy() {} } |
您通常需要在组件被销毁时取消订阅,但Angular将会越来越多地处理它,例如在Angular4的新的次要版本中,他们有此部分用于路由取消订阅:
Do you need to unsubscribe? As described in the
ActivatedRoute: the one-stop-shop for route information section of the
Routing & Navigation page, the Router manages the observables it
provides and localizes the subscriptions. The subscriptions are
cleaned up when the component is destroyed, protecting against memory
leaks, so you don't need to unsubscribe from the route paramMap
Observable.
另外下面的例子是一个很好的例子,从Angular创建一个组件并在之后销毁它,看看组件如何实现OnDestroy,如果你需要onInit,你也可以在你的组件中实现它,比如implements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import { Component, Input, OnDestroy } from '@angular/core'; import { MissionService } from './mission.service'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'my-astronaut', template: ` <p> {{astronaut}}: {{mission}} <button (click)="confirm()" [disabled]="!announced || confirmed"> Confirm </button> </p> ` }) export class AstronautComponent implements OnDestroy { @Input() astronaut: string; mission = '<no mission announced>'; confirmed = false; announced = false; subscription: Subscription; constructor(private missionService: MissionService) { this.subscription = missionService.missionAnnounced$.subscribe( mission => { this.mission = mission; this.announced = true; this.confirmed = false; }); } confirm() { this.confirmed = true; this.missionService.confirmMission(this.astronaut); } ngOnDestroy() { // prevent memory leak when component destroyed this.subscription.unsubscribe(); } } |
上述情况的另一个简短补充是:
- 始终取消订阅,当订阅流中的新值不再需要或无关紧要时,在少数情况下会导致触发器数量减少和性能提升。诸如订阅数据/事件不再存在的组件或者需要新订阅全新流(刷新等)的情况是取消订阅的一个很好的例子。
如果需要取消订阅,可以使用以下操作符来进行可观察的管道方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import { Observable, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { OnDestroy } from '@angular/core'; export const takeUntilDestroyed = (componentInstance: OnDestroy) => < T >(observable: Observable< T >) => { const subjectPropertyName = '__takeUntilDestroySubject__'; const originalOnDestroy = componentInstance.ngOnDestroy; const componentSubject = componentInstance[subjectPropertyName] as Subject || new Subject(); componentInstance.ngOnDestroy = (...args) => { originalOnDestroy.apply(componentInstance, args); componentSubject.next(true); componentSubject.complete(); }; return observable.pipe(takeUntil< T >(componentSubject)); }; |
它可以像这样使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import { Component, OnDestroy, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ template: '' }) export class SomeComponent implements OnInit, OnDestroy { ngOnInit(): void { const observable = Observable.create(observer => { observer.next('Hello'); }); observable .pipe(takeUntilDestroyed(this)) .subscribe(val => console.log(val)); } ngOnDestroy(): void { } } |
运算符包装组件的ngOnDestroy方法。
重要提示:运算符应该是可观察管道中的最后一个。
在SPA应用程序中的ngOnDestroy函数(angular lifeCycle)对于每个订阅,您需要取消订阅它。优点=>防止状态变得太重。
例如:
在component1中:
1 2 3 4 5 6 7 | import {UserService} from './user.service'; private user = {name: 'test', id: 1} constructor(public userService: UserService) { this.userService.onUserChange.next(this.user); } |
在服务中:
1 2 3 | import {BehaviorSubject} from 'rxjs/BehaviorSubject'; public onUserChange: BehaviorSubject = new BehaviorSubject({}); |
在component2中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import {Subscription} from 'rxjs/Subscription'; import {UserService} from './user.service'; private onUserChange: Subscription; constructor(public userService: UserService) { this.onUserChange = this.userService.onUserChange.subscribe(user => { console.log(user); }); } public ngOnDestroy(): void { // note: Here you have to be sure to unsubscribe to the subscribe item! this.onUserChange.unsubscribe(); } |
对于处理订阅,我使用"Unsubscriber"类。
这是Unsubscriber类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | export class Unsubscriber implements OnDestroy { private subscriptions: Subscription[] = []; addSubscription(subscription: Subscription | Subscription[]) { if (Array.isArray(subscription)) { this.subscriptions.push(...subscription); } else { this.subscriptions.push(subscription); } } unsubscribe() { this.subscriptions .filter(subscription => subscription) .forEach(subscription => { subscription.unsubscribe(); }); } ngOnDestroy() { this.unsubscribe(); } } |
并且您可以在任何组件/服务/效果等中使用此类。
例:
1 2 3 4 5 6 7 | class SampleComponent extends Unsubscriber { constructor () { super(); } this.addSubscription(subscription); } |