Як уникнути витоків пам'яті при підписках?
Щоб уникнути витоків пам'яті при підписках, головне правило: вчасно відписуватися.
Ось як це робиться на практиці:
1. Зберігати підписку і викликати unsubscribe()
ts
subscription: Subscription;
ngOnInit() {
this.subscription = this.myStream$.subscribe(data => ...);
}
ngOnDestroy() {
this.subscription.unsubscribe(); // закрили потік
}2. Використовувати takeUntil() з Subject
Підходить, якщо у тебе багато підписок:
ts
private destroy$ = new Subject<void>();
ngOnInit() {
this.myStream$
.pipe(takeUntil(this.destroy$))
.subscribe(...);
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}Все, що було в takeUntil, автоматично відписується.
3. Використовувати async пайп у шаблоні
html
<div *ngIf="value$ | async as value">{{ value }}</div>Angular сам відписується, коли компонент знищується. Це найбезпечніший варіант у шаблоні.
4. take(n) і first() - для одноразових підписок
Якщо тобі потрібне тільки одне значення з потоку:
ts
this.data$.pipe(first()).subscribe(...);або
ts
this.data$.pipe(take(1)).subscribe(...);Потік завершиться сам, нічого відписувати не потрібно.
Висновок:
Щоб не було витоків:
- Завжди відписуйся в
ngOnDestroy() - Використовуй
takeUntil()абоasync - Не залишай нескінченні
subscribe()без контролю
Некерована підписка = потік, що висить = витік пам'яті.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.