Use cases/takeUntilDestroyed — современная очистка Angular
Use cases · 35 流
takeUntilDestroyed — современная очистка Angular
Паттерн
Старый способ убирать подписки в компоненте — Subject destroy$ + takeUntil(destroy$) + destroy$.next() в ngOnDestroy. Современный Angular даёт takeUntilDestroyed() — то же самое, но без boilerplate, привязано к DestroyRef.
Какую проблему решаем
Подписки на интервалы, DOM-события, Subjects, WebSocket не завершаются сами. Если компонент уничтожен, а подписка живёт — она будет дёргать DOM, которого больше нет, и держать ссылки на удалённые объекты. Утечка памяти и ошибки в консоли.
Операторы и зачем они нужны
takeUntil(destroy$) — классический способ. Каждая подписка отписывается, когда destroy$ эмитит.
finalize — показывает момент teardown, удобен для логов и debug.
takeUntilDestroyed() — современный аналог. Берёт destroy signal из Angular DestroyRef автоматически.
Подводные камни
HTTP one-shot complete сам, но это не отменяет cleanup для valueChanges, interval, Router events и WebSocket — они вечные.
Ручной destroy$ требует и next(), и complete() в ngOnDestroy. Забыли complete — Subject будет удерживать подписчиков в тестах.
takeUntilDestroyed() вне injection context (вне constructor/факторов) — нужен явный DestroyRef-аргумент.
Что в итоге получаем
Подписки закрываются в момент destroy автоматически. Меньше boilerplate, меньше шансов забыть.