Об subscribe() vs async
Задуматься об этом выборе меня заставило архитектурное rxjs tslint правило rxjs-prefer-async-pipe
:
Disallows the calling of subscribe within an Angular component.
Оно гласит, что запрещено вызывать метод subscribe()
в Angular компонентах. Стало интересно откуда ноги растут.
Недавно наткнулся на статью The Ultimate Answer To The Very Common Angular Question: subscribe() vs | async Pipe, где подбробно разбираются оба подхода.
subscribe() vs async
Отобразить значение Observable
возможно 2 способам:
- Вручную: метод
subscribe()
-> сохранение состояние в коде компонентаtodos$.subscribe(todos => this.todos = todos)
Метод требует ручной отписки, например
takeUntil(destroy$)
илиunsubscribre()
. - Автоматически:
| async
pipe -> разворачивание состояние прямо в шаблоне компонента<li *ngFor="let todo of todos$ | async"></li>`
Работает магия. Метод не требует ручной отписки.
В привидённой статье оказалось 2 интересных момента:
Касательно
OnPush
стратегии обнаружения изменений.- Подписка на
Observable
вручную в хукеngOnInit()
не отображает изменений состояния в шаблоне. Требуется вручную вызыватьmarkForCheck()
внутри подписки. - !!!
async
работает сOnPush
стратегией из коробки! Просто убедитесь, что всегда приходят новые объекты (immutable logic).
- Подписка на
Решение с несколькими
| async
pipes развёрнутых в одну переменную:
P.S. Такие скриншоты кода делаются через сервис https://carbon.now.sh/
P.P.S.
<ng-container
*ngIf="
{
title: title$ | async,
group: group$ | async,
state: buttonState$ | async,
config: config$ | async
} as data;
else loading
"
[formGroup]="data.group"
(ngSubmit)="onSubmit()"
></ng-container>