Angular组件卸载后rxjs订阅没清理导致内存泄漏怎么办?

公孙莉莉 阅读 73

我在Angular项目里用Subject订阅了服务端数据,按官方教程在ngOnDestroy里调用了unsubscribe,但内存还是持续上涨。明明组件卸载了,为什么订阅没断开?

代码是这样写的:this.subscription = this.service.getData().subscribe(...),然后在 ngOnDestroy() { this.subscription.unsubscribe() }

但用Chrome性能分析发现,组件多次切换后服务端请求还在继续。尝试过把unsubscribe写成箭头函数,或者用takeUntil操作符,都没解决。是不是因为服务端用了长连接?或者我应该在服务层统一管理订阅?


// service.ts
private dataSubject = new Subject();
getData() {
  return interval(1000).pipe(tap(() => this.dataSubject.next()));
}

// component.ts
subscription!: Subscription;
ngAfterViewInit() {
  this.subscription = this.service.dataSubject.subscribe(data => {
    // 处理数据
  });
}
ngOnDestroy() {
  this.subscription.unsubscribe();
}

卡在哪儿了呢?明明按教程写了清理代码,但Chrome的Performance面板显示组件卸载后请求还在继续

我来解答 赞 13 收藏
二维码
手机扫码查看
2 条解答
慕容子阳
问题出在服务层的 interval 没清理,组件销毁时只是断开了订阅,但源头还在持续发射数据。改成这样:

// service.ts
private dataSubject = new Subject();
private stopPolling$ = new Subject();
getData() {
return interval(1000).pipe(
tap(() => this.dataSubject.next()),
takeUntil(this.stopPolling$)
);
}
stop() {
this.stopPolling$.next();
this.stopPolling$.complete();
}

// component.ts
ngAfterViewInit() {
this.service.getData().subscribe();
}
ngOnDestroy() {
this.service.stop();
}


总结一下:服务层加个 stopPolling$ 控制流,组件销毁时调用 stop() 停掉源头。别忘了 complete() 收尾,不然还是有内存泄漏风险。
点赞
2026-02-15 16:20
春景 ☘︎
你用的是 interval 创建的数据流,组件卸载后 interval 不会自动停止。用 takeUntil 操作符配合 ngOnDestroy 就行了:

private destroy$ = new Subject();

ngAfterViewInit() {
this.service.dataSubject
.pipe(takeUntil(this.destroy$))
.subscribe(data => { /* 处理数据 */ });
}

ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
点赞 10
2026-02-03 20:04