RxJS: `refCount: false` в ShareReplay в сервисе с ограниченной областью действия: будет ли он завершен и будет ли собран мусор при уничтожении сервиса?

Цель:

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

shareReplay({refCount: false, bufferSize: 1})

Наблюдаемый объект объявляется внутри службы, не предоставляемой root, поэтому он будет уничтожен вместе с его обеспечивающим компонентом.

Вопросы:

  • Что произойдет с наблюдаемым, когда компонент + сервис + все подписчики будут уничтожены?

    • Будет ли он завершен и готов к вывозу мусора?
    • Или refCount: false заставит Observable и, следовательно, окружающий контекст (т. е. сервис) храниться где-то в памяти, что приведет к утечке памяти?
  • Нужно ли мне предоставить какой-нибудь помощник по уничтожению, например takeUntilDestroyed() в этом случае, в конце наблюдаемого канала после ShareReplay?

Мысли:

Насколько я знаю

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

  2. если наблюдаемый объект и его подписка находятся в том же контексте, что и уничтоженный контекст, утечки не должно возникнуть.

В случае с этим ограниченным сервисом я предполагал, что применим случай 2 и внутренняя подписка refCount:false будет уничтожена вместе с окружающим контекстом, но я не уверен.

«shareplay» не имеет никакого отношения к тому, подписались вы или нет. Shareplay позволяет сделать холодный наблюдаемый объект горячим, а это означает, что будущие подписчики получат последнее значение (в случае refCount: false, bufferSize: 1), отправленное потоком во время первой подписки. Утечки памяти не возникают, если вы не отписываетесь от подписки.

Tim 26.08.2024 15:54

Да, вам нужно предоставить помощника по уничтожению. Эта ошибка (или ожидаемое поведение?) все еще присутствует.

Tortila 27.08.2024 10:08

@ Тим, я должен не согласиться. Пожалуйста, ознакомьтесь с документацией в исходном коде ShareReplay: github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/…shareReplay действительно создает внутреннюю подписку, которая сразу же становится активной в подключенном ReplaySubject. как появится первый подписчик. С refCount: false эта подписка продлится даже тогда, когда ни один подписчик больше не активен.

manuelkue 29.08.2024 15:12
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
3
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам придется использовать takeUntilDestroyed или аналогичный подход в своем сервисе, чтобы убедиться, что все было правильно очищено.

Я создал простое приложение, воспроизводящее ваш вариант использования: https://codesandbox.io/p/devbox/vigilant-babycat-f7kt2p

Если вы откроете DevTools и прокомментируете строки 70-71 в test.service.ts, вы увидите, что ваши подписки не очищаются автоматически, если refCount: false. Это потому, что shareReplay немного сложнее, в конечном итоге у вас будет как минимум две подписки: первая подписка внутри share (вы не можете отписаться от нее вручную), остальные — из вашего кода во внутреннюю shareReplayReplaySubject (️ 🔁 исходный код ).

К вашему сведению, first необходим для имитации HTTP-ответа от внутреннего сервера.

Кажется, ваша ссылка на codeandbox неправильная.

manuelkue 28.08.2024 15:11

@manuelkue, моя вина. теперь должно быть правильно

Volodymyr Usarskyy 28.08.2024 18:43

Другие вопросы по теме