Week 09 · Day 05 — 記憶體管理:takeUntil
學習目標
- 用
takeUntil自動停止訂閱 - 在
ngOnDestroy完成清理 - 避免因未退訂造成的記憶體洩漏
重點
問題:訂閱沒退訂 → 記憶體洩漏 - Observable 若沒退訂,元件銷毀後仍會觸發回呼 - 可能存取已銷毀的元件 → 錯誤或洩漏
用 takeUntil 清理
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({ ... })
export class SmartComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
ngOnInit(): void {
this.dataService.getData()
.pipe(takeUntil(this.destroy$)) // destroy$ 結束時停止訂閱
.subscribe(data => {
this.data = data;
});
}
ngOnDestroy(): void {
this.destroy$.next(); // 通知所有 takeUntil 停止
this.destroy$.complete();
}
}
原理
- takeUntil(notifier$):當 notifier$ 發出 next 或 complete,就結束訂閱
- 在 ngOnDestroy 觸發 destroy$.next() → 所有掛 takeUntil 的訂閱自動退訂
最常見對策
- 所有呼叫 subscribe() 的地方都記得掛 takeUntil(this.destroy$)
- destroy$ 是元件常見的慣用命名
實作
- 建立元件訂閱
getData() - 用
takeUntil(this.destroy$)包住 - 在
ngOnDestroy執行next()+complete() - 切換頁面確認訂閱已停止(console 無殘留 log)
作業
- 建立
destroy$並在ngOnDestroy觸發 - 每個訂閱用
takeUntil包住 - 說明未退訂為什麼造成記憶體洩漏