在 Angular 2 中防止内存泄漏?
Prevent memory leaks in Angular 2?
在 Angular 2 中,是否有任何关于内存管理的具体陷阱,我应该注意?
为了避免可能的泄漏,管理组件状态的最佳做法是什么?
具体来说,我在ngOnDestroy
方法中看到了一些人。我应该一直这样做吗?
在 Angular 1.X 中,我知道当 $scope
被销毁时,其上的所有侦听器也会自动销毁。 Angular 2 个分量中的可观察量怎么样?
@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?
}
};
根据@katspaugh 的要求
在您的特定情况下,无需手动取消订阅,因为这是异步管道的工作。
检查 AsyncPipe 的 source code。为简洁起见,我发布了相关代码
class AsyncPipe implements PipeTransform, OnDestroy {
// ...
ngOnDestroy(): void {
if (isPresent(this._subscription)) {
this._dispose();
}
}
如您所见,异步管道实现了 OnDestroy,当它被销毁时,它会检查是否有订阅并将其删除。
在这种特定情况下,您将重新发明轮子(很抱歉重复一遍)。这并不意味着您不能't/shouldn在任何其他情况下取消订阅,例如您提到的情况。在这种情况下,用户在组件之间传递 Observable 以进行通信,因此最好手动取消订阅。
我不知道框架是否可以检测到任何 alive 订阅并在组件被销毁时自动取消订阅,这当然需要更多调查。
我希望这对异步管道有所澄清。
您不必像 http.get() 之后那样取消订阅标准订阅。
但是您必须取消订阅您的自定义主题。如果您有一些组件,并且在其中订阅了服务中的某个主题,那么每次您显示该组件时,新订阅都会添加到主题中。
请检查一下:
我个人的方法——我所有的组件都是从这个很好的扩展而来的 class:
import { OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs/Subject';
/**
* A component that cleans all subscriptions with oneself
*
* @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(){}
}
我只是在每次订阅之前添加 super() 调用构造函数和 .takeUntil(this.ngUnsubscribe):
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
})
}
}
在 Angular 2 中,是否有任何关于内存管理的具体陷阱,我应该注意?
为了避免可能的泄漏,管理组件状态的最佳做法是什么?
具体来说,我在ngOnDestroy
方法中看到了一些人
在 Angular 1.X 中,我知道当 $scope
被销毁时,其上的所有侦听器也会自动销毁。 Angular 2 个分量中的可观察量怎么样?
@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?
}
};
根据@katspaugh 的要求
在您的特定情况下,无需手动取消订阅,因为这是异步管道的工作。
检查 AsyncPipe 的 source code。为简洁起见,我发布了相关代码
class AsyncPipe implements PipeTransform, OnDestroy {
// ...
ngOnDestroy(): void {
if (isPresent(this._subscription)) {
this._dispose();
}
}
如您所见,异步管道实现了 OnDestroy,当它被销毁时,它会检查是否有订阅并将其删除。
在这种特定情况下,您将重新发明轮子(很抱歉重复一遍)。这并不意味着您不能't/shouldn在任何其他情况下取消订阅,例如您提到的情况。在这种情况下,用户在组件之间传递 Observable 以进行通信,因此最好手动取消订阅。
我不知道框架是否可以检测到任何 alive 订阅并在组件被销毁时自动取消订阅,这当然需要更多调查。
我希望这对异步管道有所澄清。
您不必像 http.get() 之后那样取消订阅标准订阅。 但是您必须取消订阅您的自定义主题。如果您有一些组件,并且在其中订阅了服务中的某个主题,那么每次您显示该组件时,新订阅都会添加到主题中。
请检查一下:
我个人的方法——我所有的组件都是从这个很好的扩展而来的 class:
import { OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs/Subject';
/**
* A component that cleans all subscriptions with oneself
*
* @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(){}
}
我只是在每次订阅之前添加 super() 调用构造函数和 .takeUntil(this.ngUnsubscribe):
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
})
}
}