什么时候应该存储订阅和调用unsubscribe()对销毁事件和什么时候可以忽略它们。保存所有订阅会给组件代码带来很多麻烦。
HTTP Client Guide忽略订阅,像这样:
getHeroes() { this.heroService.getHeroes() .subscribe( heroes => this.heroes = heroes,error => this.errorMessage = <any>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.
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(); }
对于这个问题有(2)种观测值 – 有限值和无限值。
http Observables产生有限(1)的值,像DOM事件侦听器一样,Observable产生无限值。
如果你手动调用订阅然后从无限观察者中取消订阅,不要担心有限的,RxJs会照顾他们。
来源1
我跟踪了一个回答从Rob Wormald在Angular的Gitter here。
他说(为了清晰起见,重点是我的)
if its a single-value-sequence (like an http request)
the manual cleanup is unnecessary (assuming you subscribe in the controller manually)i should say “if its a sequence that completes” (of which single value sequences,a la http,are one)
if its an infinite sequence,you should unsubscribe which the async pipe does for you
他还提到在这个youtube video观察者,他们清理自己…在观察者的语境完成(像承诺,总是完成,因为他们总是产生1价值和结束 – 我们从来不担心取消订阅承诺,确保他们清理xhr事件监听器,对吗?)。
来源2
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.
我们的观察词的时间是什么时候比我们的订阅有更长的寿命?
当在Observable完成之前(或不在’long’之前)销毁的组件内创建订阅时,它适用。
我读这个意思,如果我们订阅一个http请求或一个observable发出10个值,我们的组件在http请求返回或10个值被释放之前被销毁,我们仍然确定!
当请求返回或第10个值最终发出时,Observable将完成并且所有资源将被清除。
来源3
如果我们从同一个Rangle指南看看this example,我们可以看到对route.params的订阅需要一个取消订阅(),因为我们不知道这些params将停止改变(发出新的值)。
可以通过导航离开来销毁组件,在这种情况下路由参数很可能仍在改变(它们可以在技术上改变,直到应用结束),并且仍然分配在订阅中分配的资源,因为还没有完成。
—编辑1
来源4
在这个video from NgEurope Rob Wormald也说你不需要取消订阅路由器可观察。他还在这个video from November 2016中提到http服务和ActivatedRoute.params。
—编辑2(2016/12/28)
来源5
Angular的教程,路由章节现在说明如下:“路由器管理它提供的可观察值并且本地化订阅。当组件被销毁时,订阅被清除,防止内存泄漏,所以我们不需要取消订阅路由参数Observable。 – Mark Rajcok
这里是一个discussion Github问题的Angular docs关于路由器可观察,沃德·贝尔提到,所有这一切的澄清是在作品中。