admin管理员组文章数量:1194107
In Angular 2 are there any specific pitfalls regarding memory management, I should be aware of?
What are the best practices to manage the state of components in order to avoid possible leaks?
Specifically, I've seen some people unsubscribing from HTTP observables in the ngOnDestroy
method. Should I always do that?
In Angular 1.X I know that when a $scope
is destroyed, all listeners on it are destroyed as well, automatically. What about observables in Angular 2 components?
@Component({
selector: 'library',
template: `
<tr *ngFor="#book of books | async">
<td>{{ book.title.text }}</td>
<td>{{ book.author.text }}</td>
</tr>
`
})
export class Library {
books: Observable<any>;
constructor(private backend: Backend) {
this.books = this.backend.get('/texts'); // <-- does it get destroyed
// with the component?
}
};
In Angular 2 are there any specific pitfalls regarding memory management, I should be aware of?
What are the best practices to manage the state of components in order to avoid possible leaks?
Specifically, I've seen some people unsubscribing from HTTP observables in the ngOnDestroy
method. Should I always do that?
In Angular 1.X I know that when a $scope
is destroyed, all listeners on it are destroyed as well, automatically. What about observables in Angular 2 components?
@Component({
selector: 'library',
template: `
<tr *ngFor="#book of books | async">
<td>{{ book.title.text }}</td>
<td>{{ book.author.text }}</td>
</tr>
`
})
export class Library {
books: Observable<any>;
constructor(private backend: Backend) {
this.books = this.backend.get('/texts'); // <-- does it get destroyed
// with the component?
}
};
Share
Improve this question
edited May 23, 2017 at 12:02
CommunityBot
11 silver badge
asked Dec 25, 2015 at 9:56
katspaughkatspaugh
17.9k12 gold badges67 silver badges105 bronze badges
4
|
2 Answers
Reset to default 16As requested by @katspaugh
In your specific case there's no need to unsubscribe manually since that's the Async pipe's job.
Check the source code for AsyncPipe. For brevity I'm posting the relevant code
class AsyncPipe implements PipeTransform, OnDestroy {
// ...
ngOnDestroy(): void {
if (isPresent(this._subscription)) {
this._dispose();
}
}
As you can see the Async pipe implements OnDestroy, and when it's destroyed it checks if is there some subscription and removes it.
You would be reinventing the wheel in this specific case (sorry for repeating myself). This doesn't mean you can't/shouldn't unsubscribe yourself in any other case like the one you referenced. In that case the user is passing the Observable between components to communicate them so it's good practice to unsubscribe manually.
I'm not aware of if the framework can detect any alive subscriptions and unsubscribe of them automatically when Components are destroyed, that would require more investigation of course.
I hope this clarifies a little about Async pipe.
You do not have to unsubscribe from standard subscriptions like after http.get(). But you DO have to unsubscribe from subscription on your custom Subjects. If you have some component and inside it you subscribing to some Subject in your service, then every time you showing that component new subscription will be added to the Subject.
Please check this out: Good solution to make your components 'clean'
My personal approach - all my components are extended from this nice class:
import { OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs/Subject';
/**
* A component that cleans all subscriptions with oneself
* https://stackoverflow.com/questions/38008334/angular-rxjs-when-should-i-unsubscribe-from-subscription
* @class NeatComponent
*/
export abstract class NeatComponent implements OnDestroy, OnInit {
// Add '.takeUntil(this.ngUnsubscribe)' before every '.subscrybe(...)'
// and this subscriptions will be cleaned up on component destroy.
protected ngUnsubscribe: Subject<any> = new Subject();
public ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
public ngOnInit(){}
}
And I just adding super() call to constructor and .takeUntil(this.ngUnsubscribe) before every subscribe:
import { NeatComponent } from '../../types/neat.component';
@Component({
selector: 'category-selector',
templateUrl: './category-selector.component.pug'
})
export class CategorySelectorComponent extends NeatComponent {
public constructor(
private _shopService: ShopsService
) { super(); }
public ngOnInit() {
this._shopService.categories.takeUntil(this.ngUnsubscribe)
.subscribe((categories: any) => {
// your code here
})
}
}
本文标签: javascriptPrevent memory leaks in Angular 2Stack Overflow
版权声明:本文标题:javascript - Prevent memory leaks in Angular 2? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738499364a2090176.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
ngOnDestroy
is not necessary, theAsync
pipe handle all that for you. That would be a good practice, instead of subscribing yourself let the pipe do that everything for you. – Eric Martinez Commented Dec 25, 2015 at 11:54