方法来自 stackoverflow
原文回答 摘录如下:
I spoke with Ward Bell about this question at NGConf (I even showed him this answer which he said was correct) but he told me the docs team for Angular had a solution to this question that is unpublished (though they are working on getting it approved). He also told me I could update my SO answer with the forthcoming official recommendation.
The solution we should all use going forward is to add a private ngUnsubscribe: Subject = new Subject();
field to all components that have .subscribe()
calls to Observable
s within their class code.
We then call this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();
in our ngOnDestroy()
methods.
The secret sauce (as noted already by @metamaker) is to call .takeUntil(this.ngUnsubscribe)
before each of our .subscribe()
calls which will guarantee all subscriptions will be cleaned up when the component is destroyed.
Example:
import { Subject } from 'rxjs/Subject';
import { MyThingService } from '../my-thing.service';
@Component({
selector: 'my-thing',
templateUrl: './my-thing.component.html'
})
export class MyThingComponent implements OnDestroy, OnInit {
private ngUnsubscribe: Subject = new Subject();
constructor(
private myThingService: MyThingService,
) { }
ngOnInit() {
this.myThingService.getThings()
.takeUntil(this.ngUnsubscribe)
.subscribe(things => console.log(things));
/* if using lettable operators in rxjs ^5.5.0
this.myThingService.getThings()
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(things => console.log(things));
*/
this.myThingService.getOtherThings()
.takeUntil(this.ngUnsubscribe)
.subscribe(things => console.log(things));
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}