Pull to refresh

Comments 18

Автору респект! В статье и проблемы, и их решения. Контента по ангуляру меньше, чем хотелось бы. К сожалению...

С take(1) тоже надо отписываться в обязательном порядке, так как если в течение жизни компонента ни одного значения не придет — вы все ещё останетесь на него подписаны

Спасибо за комментарий. В контексте статьи я хотел показать что после получения первого значения нужно завершать стрим чтобы не тратить ресурсы на его обработку ( конечно если это подходит по логике ). Но в общем случае вы правы - нужно отписываться. Сделал поправку, добавил takeUntil(this.onDestroy$) в пример с take(1).

Примечание: “холодный” стрим сам завершится после выдачи первого значения, для него данные операторы избыточны.

Холодный стрим не завершается после первого значения, только если он не выдает только одно значение. Это такой же стрим как и горячий, он может иметь сколько угодно значений и может даже никогда не завершиться или может никогда не выдать ни одного значения.

Отличие от горячего, что он начинает подкапотную работу только после подписки на него.

Вы правы, тут я был неосторожен. На проекте мы часто используем стримы выдающие 1 значение, но конечно упоминание "холодности" было некорректно. Убрал это примечание, оно там вообще не нужно.

takeUntilDestroyed чисто ангуляровский оператор. Я предлагаю заменить его в статье на takeUntil, тогда не только ангулярщику будет понятно как можно регулировать время жизни подписки и безопасно отписываться.

playersCount$: Observable<number> = this.api.getPlayersCount().pipe(

takeUntil(this.onDestroy$), // также можно использовать takeUntilDestroyed

shareReplay(1)

);

Во-первых, takeUntil должен быть всегда последним.

Во-вторых, этот оператор надо добавлять только непосредственно перед подпиской, в пайпе обсервабла он не нужен

Во-первых, takeUntil должен быть всегда последним.

Это не так, takeUntil ставится перед shareReplay и некоторыми другими операторами. Пруф.

Во-вторых, этот оператор надо добавлять только непосредственно перед подпиской, в пайпе обсервабла он не нужен

Я его поставил перед shareReplay по причине выше. К тому же в статье приводятся отдельные куски кода исключительно для примера. В этом случае вообще нет подписки, она за скобками.

по ссылке никаких пруфов нет, есть только одно предложение что есть операторы которые могут себя не так вести, но все это от их неправильного использования. Например, toArray, который ожидает комплита, не должен быть завязан на комплит от takeUntil, а от чего то другого, например, получить n значений. takeUntil только для отписки, а не для комплита потока (если мы говорим только о случаях его использования для отписки, тк есть и другие кейсы, но мы их в данном случае опустим).

Пряча takeUntil внутри pipe какого то observable, мы лишаемся понимания произойдет ли отписка и в принципе мы не должны о таком думать. Поэтому takeUntil используется только в связке с subscribe, в других случаях он либо избыточен или даже вреден.

По ссылке есть вся необходимая информация, в частности про shareReplay - если вы нажмете "Further reading" и перейдете на статью с объяснением. Внизу есть раздел An update.

возвращаясь к пункту 2 и взяв ваш пример с playersCount$.

допустим есть несколько случаев его использования

1. в темплейте `playersCount$ | async`

  1. создание другого observable `observable$ = playersCount$.pipe(switchMap(count) => apiCall)`

  2. подписка `playersCount$.pipe(map(...),mergeMap(...)).subscribe()`

должен ли разработчик подумать надо ли добавить takeUntil в какой либо из пайпов или знания что в пайпе playersCount$ он есть этого достаточно?

Но да, с shareReplay есть проблема при отписке и по хорошему надо при менять refCount с shareReplay когда это возможно, тогда проблемы не будет.

Либо shareу которого по умолчанию resetOnError , resetOnComplete и resetOnRefCountZero установлены в true. или ставить перед ним takeUntil, что выглядит не очень

или ставить перед ним takeUntil, что выглядит не очень

Тут уже вопрос вкусов и конкретной ситуации, я посчитал этот вариант безопасным и вполне корректным для своего примера.

Кстати отписка и нюансы использования share в контексте Ангулара тянут на отдельную статью ( это как минимум ). Нет ли у вас желания написать ее? По моему отличная тема для дебюта на Хабре. Комментарии сложно найти и они не включают все кейсы, а вот отдельная статья со всеми нюансами была бы очень полезна сообществу. Что скажите?

хорошая подводка, 5 баллов ).
Я на хабре не пишу (пока), на медиуме пара статей

но надо подумать

на самом деле, поигравшись и переосмыслив я соглашусь, что shareReplay(n) лучше юзать с takeUntil перед ним

Sign up to leave a comment.

Articles