tgoop.com/summon_the_coder/21
Last Update:
RxJS: Отписки? А точно надо?
Кажется, тема отписок от потоков уже давно закрыта, но снова и снова встречаю обсуждения нужности отписки от потоков, поэтому решил собрать информацию в одном месте и разложить все по своим местам. Давайте сначала разберемся с терминами.
Unsubscribe - отписка от потока. Сообщаем источнику значений, что текущий подписчик больше не хочет получать новые значения. Если у потока остались другие подписчики, то они продолжат получать новые значения.
Complete - завершение потока. Завершенный поток перестает уведомлять всех подписчиков о новых значениях.
Finalization - освобождение ресурсов, занятых потоком. Данный процесс происходит всегда при ошибке, завершении потока, отписке.
Для чего мы отписываемся или завершаем потоки:
- Избежание сайд-эффектов. При активной подписке могут выполнятся колбэк или цепочка операторов, которые необходимо запускать только если компонент инициализирован.
- Освобождение ресурсов памяти и борьба с неконтролируемыми утечками памяти.
А теперь самое интересное, ситуации, когда отписка не требуется (если поток простой и содержит только одну из описанных ниже сущностей):
- Потоки, которые в конечном итоге завершаются (of, from, timer(1000), first итд).
- Использование сервиса ActivatedRoute. Данный сервис и его потоки изолированы от Router сервиса. Router уничтожает маршрутизируемый компонент, когда он больше не нужен вместе со всеми зависимостями.
- Использование сервиса HttpClient (создает потоки, которые в конечном итоге завершаются).
В этом месте я хочу задать вопросы. Готовы ли вы анализировать каждый поток с ручной подпиской и тратить на это свое время (поток может трансформироваться, добавится таймер или какой-то хитрый внутренний поток)? А как же консистентность кодовой базы: где-то есть подписка, где-то нет? Вы точно уверены, что все члены команды знают тонкости отписок и не допустят утечек?
Не слишком ли много вопросов для проблемы, которая решается одной строчкой кода? Не проще ли всегда отписываться, чем пытаться учесть все нюансы?
Подготовил список из проверенных практик для управления подписками:
- Используйте линтер: добавьте eslint-plugin-rxjs и eslint-plugin-rxjs-angular для автоматической проверки отписок или полного запрета ручных подписок.
- Избегайте ручных подписок: комбинируйте потоки через merge, zip или combineLatest, чтобы привязать их к шаблону с автоотпиской.
- Async pipe: используйте в шаблонах, чтобы автоматически управлять подписками.
- Операторы takeUntil или takeUntilDestroyed: используйте эти операторы последними в цепочке операторов для автоматического завершения подписки при уничтожении компонента.
- toSignal (доступно с Angular 16 в статусе dev preview): конвертируйте потоки в сигналы с автоматическим управлением подписками.
- Higher-order observables: избавляйтесь от "подписок внутри подписок", чтобы избежать утечек памяти.
- Библиотеки: если вы используете Angular ниже 16 версии, попробуйте @ngneat/until-destroy или напишите кастомное решение.
Отписка — это не лишняя работа, а гарантия стабильности и удобства сопровождения вашего кода. И ответ на вопрос из заголовка - отписывайтесь всегда.
Ну и напоследок я собрал всевозможные актуальные способы отписок в одном Stackblitz. Получился своеобразный справочник по отпискам — каждый способ сопровожден комментариями с пояснениями. Делитесь этим проектом с начинающими разработчиками и теми, кто только открывает для себя красоту реактивного программирования!
@summon_the_coder
#RxJS #Angular #ReactiveProgramming
BY SUMMON_THE_CODER
Share with your friend now:
tgoop.com/summon_the_coder/21
