I'm currently wondering about angular subscription and unsubscription. There is a lot of stuff on the subject, so I'm a bit lost in all of this.
When should I unsubscribe from subscription ? What happens if I don't, ever, unsubscribe from them ? I never encounter any errors from reliquat subscription.
Is there a way to auto unsubscribe from everything in a component/app, so that I don't have to declare 1 property by subscription ? This can be very annoying :
@Component({
selector: 'subscriptionTest',
template: `...`,
})
export class SubTestComponent {
first;
second;
third;
constructor(private remote: RemoteService){}
ngOnInit() {
this.first = remote.getSomeData().subscribe(data => // do something);
this.second = Observable.interval(500).subscribe(event => // do something);
this.third = remote.getSomeOtherData().subscribe(data => // do something);
}
ngOnDestroy() {
this.first.unsubscribe();
this.second.unsubscribe();
this.third.unsubscribe();
}
}
The takeUntil
operator is a simple way to "auto" unsubscribe from any subscription, example :
@Component({...})
export class AppComponent implements OnInit, OnDestroy {
destroy$: Subject<boolean> = new Subject<boolean>();
constructor(private apollo: Apollo) {
}
ngOnInit() {
this.apollo.watchQuery({
query: gql`
query getAllPosts {
allPosts {
title
description
publishedAt
}
}
`
})
.takeUntil(this.destroy$)
.subscribe(({data}) => {
console.log(data);
});
remote.getSomeData().subscribe(data => // do something);
Observable.interval(500).subscribe(event => // do something);
remote.getSomeOtherData().subscribe(data => // do something);
}
onStartInterval() {
Observable
.interval(250)
.takeUntil(this.destroy$)
.subscribe(val => {
console.log('Current value:', val);
});
}
ngOnDestroy() {
this.destroy$.next(true);
// Now let's also unsubscribe from the subject itself:
this.destroy$.unsubscribe();
}
}
You don't have to declare each subscription , only to add the .takeUntil(this.destroy$)
operator on each of them
Source : https://alligator.io/angular/takeuntil-rxjs-unsubscribe/
An amazing post about subscriptions : Angular/RxJs When should I unsubscribe from `Subscription`
If you don't want to repeat yourself, use a super class:
/**
* Unsubscribe from any Observable using takeUntil and this.destroy$
* someObservable.pipe( // lettable operators in rxjs ^5.5.0
* ...
* takeUntil(destroy$)
* )
* .subscribe(....
**/
export class Destroyer implements OnDestroy {
destroy$: Subject<boolean> = new Subject<boolean>();
ngOnDestroy() {
// Unsubscribe from whatever used takeUntil(destroy$)
this.destroy$.next(true);
// Now let's also unsubscribe from the subject itself:
this.destroy$.unsubscribe();
}
}
Use that everywhere:
export class SomeComponent extends Destroyer{
constructor(private remote: RemoteService){
super();
}
ngOnInit() {
remote.getSomeData()
.pipe(takeUntil(this.destroy$))
//.takeUntil(this.destroy$) // before rxjs ^5.5.0
.subscribe(data => {/* do something*/});
Observable.interval(500)
.pipe(takeUntil(this.destroy$))
//.takeUntil(this.destroy$) // before rxjs ^5.5.0
.subscribe(data => {/* do something*/});
}
}
// optional. You don't need ngOnDestroy everywhere.
ngOnDestroy(): void {
// Let Destroyer trigger unsubscribe
super.ngOnDestroy();
// ...SomeComponent other cleanup.
}
}
The best way is use Subscription class.
For that, you will create a variable in your component, like this...
private subs: Subscription = Subscription.EMPTY;
And then use like this...
this.subs.add(this.route.data.subscribe(...
or
this.subs.add(this.clientService.login(this.username, this.password).subscribe(...
And in your ngOnDestroy() make a unique call, like
this.subs.unsubscribe();
您可以使用第三方插件,例如ngx-auto-unsubscribe
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.