在Angular 2中有关于内存管理的任何特定缺陷,我应该知道吗?
管理组件状态以避免可能的泄漏的最佳实践是什么?
具体来说,我已经看到一些人在方法中取消订阅HTTP observablesngOnDestroy.我应该一直这样做吗?
在Angular 1.XI中,知道当a $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?
}
};
Run Code Online (Sandbox Code Playgroud) 有几种方法可以取消订阅 Angular 组件上的 observables(通过使用 ngOnDestroy)。应首选以下哪个选项?为什么(例如技术原因、性能等)?
使用 RxJS takeUntil 取消订阅
@Component({
selector: "app-flights",
templateUrl: "./flights.component.html"
})
export class FlightsComponent implements OnDestroy, OnInit {
private readonly destroy$ = new Subject();
public flights: FlightModel[];
constructor(private readonly flightService: FlightService) {}
ngOnInit() {
this.flightService
.getAll()
.pipe(takeUntil(this.destroy$))
.subscribe(flights => (this.flights = flights));
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
Run Code Online (Sandbox Code Playgroud)
显式调用 .unsubscribe(),例如通过使用单独的订阅实例
@Component({
selector: "app-flights",
templateUrl: "./flights.component.html"
})
export class FlightsComponent implements OnDestroy, OnInit {
private readonly subscriptions = new Subscription();
public flights: …Run Code Online (Sandbox Code Playgroud) 我需要在一个间隔中刷新组件页面中的数据.此外,我需要在执行某些操作后刷新数据.我在服务中使用Obeservables,以便我可以在响应准备好时订阅.我正在推送对象的订阅,以便我可以清除它ngDestroy,我认为,我有以下方法来实现相同的目标.
方法1:setInterval
我已经设置了一个间隔ngOnInit,它将以相等的间隔调用refreshData.将使用clearIntervalin ngOnDestroy方法清除interval对象.
export class MyComponent implements OnInit, OnDestroy {
private subscription: Subscription = new Subscription();
data: any;
interval: any;
ngOnInit() {
this.refreshData();
this.interval = setInterval(() => {
this.refreshData();
}, 5000);
}
ngOnDestroy() {
this.subscription.unsubscribe();
clearInterval(this.interval);
}
refreshData(){
this.subscription.add(
this.myService.getData()
.subscribe(data => {
this.data = data;
})
);
}
doAction(){
this.subscription.add(
this.myService.doAction()
.subscribe(result => {
if(result === true){
this.refreshData();
}
})
);
}
}
Run Code Online (Sandbox Code Playgroud)
Q1:在每次刷新调用时subscription,都会向对象添加一个订阅,这会增加内存使用量,如果用户保持页面打开一段时间,浏览器可能会崩溃吗?
方法2:Observable.timer
此方法使用将在刷新数据后创建的计时器.
export class MyComponent …Run Code Online (Sandbox Code Playgroud) memory-leaks subscriptions setinterval angular2-observables angular
当我知道在我的组件/类超出范围之前,observable肯定会完成(通过complete或error通知),我是否还需要取消订阅才能防止内存泄漏?换句话说,完成/错误编辑是否可以自动清理,所以我不必担心?
以下是我所询问的一个简单示例:
class AppComponent {
someInput: FormControl = new FormControl('');
private subscription: Subscription;
constructor(){
this.subscription = this.someInput.valueChanges
.subscribe(() => console.log("testing"));
}
}
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
1)我是否必须最终取消订阅?2)最重要的是,无论答案是什么,#1,答案是什么?
任何见解将不胜感激!
谢谢!
如果我有以下内容:
<div *ngIf="user$ | async as user" class="container">
<p>user.name</p>
</div>Run Code Online (Sandbox Code Playgroud)
当div上面的内容最终出现在屏幕上时,有没有办法可以执行代码?
是否可以在不手动存储的情况下获取所有"活动"订阅?
我想要unsubscribe所有"活动"订阅,并且不希望在数组或变量中引用它们中的每一个.
在Angular 2中,有一些您不需要取消订阅的可观察对象.例如http requests和activatedRoute.params.
但是当我使用switchMap时会发生什么情况,例如activatedRoute.params,并且在switchMap内部我访问一个服务,该服务返回一个observable,如果以通常的方式订阅则需要取消订阅.
像这样的东西:
this.activatedRoute.params
.switchMap((params: Params) => this.userService.getUser(+params['id']))
.subscribe((user: User) => this.user = user);
Run Code Online (Sandbox Code Playgroud)
如果我在没有switchMap且没有activateRoute.params的情况下调用this.userService,我将不得不取消订阅.
// userService.getUser() takes in optional id?: number.
this.subscription = this.userService.getUser().subscribe(
(user: User) => {
this.user = user;
}
);
Run Code Online (Sandbox Code Playgroud)
然后......
this.subscription.unsubscribe();
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果我在其上使用switchMap并调用需要取消订阅的服务,是否需要取消订阅activatedRoute.params?
如何更有效地使用路由器 Observables?例如,如果我需要加载单个路由参数(假设我们有一个类似的路由/some-resource/:id),我需要订阅路由器事件,然后订阅路由参数以获取值。这需要两次订阅和两次取消订阅。
我想要:
样本
export class SomeComponent implements OnInit, OnDestroy {
private routerSub: Subscription;
private routeSub: Subscription;
someResource: Observable<SomeResourceType>;
constructor(private someService: SomeService,
private route: ActivatedRoute,
private router: Router) {
this.routerSub = this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
this.routeSub = this.route.params.subscribe((params) => {
if (params['id']) {
this.someResource = this.someService.findById(params['id']);
// will access the resource using async pipe later
}
});
}
});
}
ngOnInit(): void {
}
ngOnDestroy(): void {
this.routerSub.unsubscribe();
this.routeSub.unsubscribe();
}
} …Run Code Online (Sandbox Code Playgroud) 我想知道如果我在我的构造函数中订阅流如下:
_eventEmitterService.event.subscribe((msg)=>{})
Run Code Online (Sandbox Code Playgroud)
因此,当我将视图更改为不同的组件并返回时,事件将从该流触发两次.每次更改组件时,是否需要取消订阅ngOnDestroy?
谢谢
angular ×10
rxjs ×7
memory-leaks ×2
typescript ×2
angularjs ×1
javascript ×1
observable ×1
rx-java ×1
setinterval ×1
unsubscribe ×1