Многоадресная рассылка rxjs/ngrx на .select

В @Component должен ли я всегда выполнять многоадресную рассылку .select(myCustomSelector)?

e.g.

this.store.select(myCustomSelector).pipe(share());

В противном случае каждый раз, когда я делаю async, будет создаваться новая подписка. Или это нормально, потому что селектор запоминается?

Мне интересно, что является хорошей практикой.


person Dolan    schedule 12.11.2018    source источник
comment
Это зависит от того, что вы хотите сделать. Но да, если вы используете несколько каналов async, вы делаете несколько подписок.   -  person martin    schedule 12.11.2018
comment
Но добавление .share() ко всем моим наблюдениям кажется мне запахом кода. Возможно, прирост производительности не столь существенен?   -  person Dolan    schedule 12.11.2018
comment
Если ваши селекторы просто выбирают что-то из магазина, я думаю, это вообще не проблема. Даже если вы выполняете некоторые вычисления в своих селекторах, использование функции createSelector гарантирует кэширование результата. Но что вы должны сделать, так это обязательно отменить подписку, когда ваш компонент будет уничтожен (вероятно, с помощью takeUntil).   -  person sloth    schedule 12.11.2018
comment
Если вы считаете, что добавление share() - это запах кода (но это не так), вы можете обернуть свои компоненты через контейнер (родительский), подписаться один раз и передать значения нужным компонентам.   -  person KiraAG    schedule 13.11.2018


Ответы (2)


Нет, вы не должны использовать share() с .select().

Но это зависит от того, какую реализацию магазина вы используете.

в ngrx, ngxs, akita хранилище поддерживается объектом, и поэтому наблюдаемое, возвращаемое из выбора, не будет вызывать никаких побочных эффектов.

затем хранилище обновляется через редюсер, и тогда все выборки получат новое значение, но, поскольку все они работают с этим единственным объектом (состоянием), это не будет проблемой производительности.

person Leon Radley    schedule 12.11.2018
comment
Но что, если, на мой взгляд, у меня несколько асинхронных каналов? Конечно, это повлияет на производительность, потому что каждая асинхронность — это новая подписка? - person Dolan; 13.11.2018
comment
Использование нескольких асинхронных каналов для данного наблюдаемого объекта является антипаттерном. этому можно помочь, подписавшись на него один раз в ngOnInit и сохранив результат в локальной переменной, а затем обязательно отписавшись в ngOnDestroy, чтобы подписка не сбрасывалась. - person Leon Radley; 13.11.2018

Почему бы просто не сделать один async на верхнем уровне внутри шаблона, а затем повторно использовать значение?

<ng-container *ngIf="myItems$ | async as myItems">
<div *ngFor="let item of myItems">....</div>
<div *ngFor="let item of myItems">....</div>
<div *ngFor="let item of myItems">....</div>
</ng-container>
person Vladimir Prudnikov    schedule 21.04.2020