我有另一个组件的shareService和subscribe:
import { Component, Input, OnDestroy } from '@angular/core';
import { MissionService } from './mission.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'my-astronaut',
template: `
<p>
{{astronaut}}: <strong>{{mission}}</strong>
<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();
}
}
我想知道我的constructor
中是否有2个订阅者,如何取消订阅ngDestroy中的两个订阅者?
我应该使用subscription2:Subscription;
?和ngDestroy this.subscription2.unsubscribe();
?
这是真的吗?
答案 0 :(得分:29)
您可以在数组ngOnDestroy()
中收集要立即取消订阅的订阅
export class AstronautComponent implements OnDestroy{
@Input() astronaut: string;
mission = "<no mission announced>";
confirmed = false;
announced = false;
subscriptions:Subscription[] = [];
constructor(private missionService: MissionService) {
this.subscriptions.push(missionService.missionAnnounced$.subscribe(
mission => {
this.mission = mission;
this.announced = true;
this.confirmed = false;
}));
this.subscriptions.push(fooService.fooObservable$.subscribe(
...
}));
}
confirm() {
this.confirmed = true;
this.missionService.confirmMission(this.astronaut);
}
ngOnDestroy(){
// prevent memory leak when component destroyed
this.subscriptions.forEach(s => s.unsubscribe());
}
}
答案 1 :(得分:16)
Subscription
可以保留子订阅并安全地取消订阅所有订阅。此方法处理可能的错误(例如,如果任何子订阅为null)。此外,如果在调用ngOnDestroy
后添加了任何订阅,则会立即取消订阅。
应注意Subscription.add()
会返回添加的订阅。因此,将add()
与subManager.add(sub1).add(sub2)
相关联会将sub2
添加到sub1
。如果sub1
在较早时间取消订阅,则会出现问题,因为它也会取消订阅sub2
。
import { OnDestroy } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { Subscription } from "rxjs/Subscription";
export class MyComponent implements OnDestroy {
ob1: Observable<number>;
ob2: Observable<number>;
subManager = new Subscription();
constructor() {
this.ob1 = Observable.interval(1000);
this.ob2 = Observable.interval(2000);
let sub1 = this.ob1.subscribe(val => console.log(val));
let sub2 = this.ob2.subscribe(val => console.log(val));
// DO NOT CHAIN add() - SEE ABOVE
this.subManager.add(sub1);
this.subManager.add(sub2);
}
ngOnDestroy() {
this.subManager.unsubscribe();
}
}
此外,订阅可以通过add()组合在一起 方法,它将子订阅附加到当前 订阅。当订阅取消订阅时,其所有子订阅 (及其孙子女)也将取消订阅。
...
如果此订阅已处于关闭状态,则通过撕裂 下行逻辑将立即执行。
答案 2 :(得分:0)
我认为,更优雅,更通用(与您有多少订阅无关)是使用rxjs包中的takeUntil运算符。
import { OnDestroy } from "@angular/core";
import { Subject, Observable } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
export class MyComponent implements OnDestroy {
ob1: any;
ob2: any;
private _endSubs: Subject<any> = new Subject();
private endSubs$ = this._endSubs.asObservable();
constructor() {
this.ob1 = Observable.interval(1000);
this.ob2 = Observable.interval(2000);
let sub1 = this.ob1.pipe(takeUntil(this.endSubs$)).subscribe(val => console.log(val));
let sub2 = this.ob2.pipe(takeUntil(this.endSubs$)).subscribe(val => console.log(val));
.... (more subscriptions here)
}
ngOnDestroy() {
this._endSubs.next();
}
}