Я хотел понять эти 3:
Предмет , поведение субъект и субъект Replay . Я хотел бы использовать их и знать, когда и почему, каковы преимущества их использования, и хотя я читал документацию, смотрел учебные пособия и искал в Google, я не смог понять этого.
Так в чем их цель? Было бы очень полезно использовать реальный случай, который не требует даже кодирования.
Я бы предпочел чистое объяснение, а не просто «a + b => c, на которое вы подписаны ....»
Спасибо
Ответы:
Это действительно сводится к поведению и семантике. С
Subject
- подписчик получит только опубликованные значения, которые были отправлены после подписки. Спросите себя, этого ли вы хотите? Нужно ли подписчику что-нибудь знать о предыдущих значениях? Если нет, то вы можете использовать это, в противном случае выберите один из других. Например, при межкомпонентной коммуникации. Допустим, у вас есть компонент, который публикует события для других компонентов по нажатию кнопки. Вы можете использовать сервис с предметом для общения.BehaviorSubject
- кешируется последнее значение. Подписчик получит последнее значение при первоначальной подписке. Семантика этого предмета состоит в том, чтобы представлять значение, которое изменяется со временем. Например, авторизованный пользователь. Первоначальный пользователь может быть анонимным пользователем. Но как только пользователь входит в систему, новым значением становится состояние аутентифицированного пользователя.BehaviorSubject
Инициализируется с начальным значением. Иногда это важно для предпочтения кодирования. Скажем, например, вы инициализируете его с помощьюnull
. Затем в вашей подписке вам нужно выполнить нулевую проверку. Может быть, ОК, а может, надоедает.ReplaySubject
- он может кэшировать до определенного количества выбросов. Все подписчики получат все кешированные значения при подписке. Когда вам понадобится такое поведение? Честно говоря, в таком поведении мне не было нужды, кроме следующего случая:Если вы инициализируете a
ReplaySubject
с размером буфера1
, тогда он фактически ведет себя так же, какBehaviorSubject
. Последнее значение всегда кэшируется, поэтому оно действует как значение, меняющееся со временем. При этом нет необходимости вnull
проверке, как в случаеBehaviorSubject
инициализации с помощьюnull
. В этом случае подписчику не передается никакого значения до первой публикации.Так что на самом деле все сводится к ожидаемому поведению (в отношении того, какой из них использовать). В большинстве случаев вы, вероятно, захотите использовать,
BehaviorSubject
потому что то, что вы действительно хотите представить, - это семантика «значения во времени». Но лично я не вижу ничего плохого в заменеReplaySubject
initialized на1
.Чего вы хотите избежать, так это использования ванили,
Subject
когда вам действительно нужно какое-то кеширование. Возьмем, к примеру, вы пишете охраннику маршрута или решение. Вы получаете некоторые данные в этом страже и устанавливаете их в сервисеSubject
. Затем в маршрутизируемом компоненте вы подписываетесь на субъект службы, чтобы попытаться получить то значение, которое было отправлено в Guard. Упс. Где ценность? Он уже был отправлен, DUH. Используйте тему "кеширование"!Смотрите также:
источник
ReplaySubject
с размером буфера 1 было именно то, что мне нужно. У меня был охранник маршрута, которому нужно было значение, но нужно было дождаться первого выброса. Таким образом, aBehaviorSubject
не сокращал его, так как мне не нужно было начальное значение (null
тоже не сработало бы, потому что я использовал его для обозначения состояния)resolve
класса защиты Angular . Моя служба данных может быть асинхронной или синхронной (если данные уже были получены). Если это было синхронно, Subject.next () запускался до того, какresolve
функция была возвращена и на нее была подписана внутренняя подписка Angular. BehaviourSubject, возможно, сработает, но мне придется явно вызывать,complete()
а также добавлятьnull
проверки для начального значения. То , что сработало было новымReplaySubject<DataType>(1)
иresolveSubject.asObservable().take(1).map(....)
.asObservable()
Observable, отправляю значениеnull
подписчикам, прежде чем я когда-либо вызовуnext()
свой ReplaySubject. Я думал, что у него не должно быть начального значения в отличие от BehaviorSubject?Удобное резюме различных наблюдаемых типов, не интуитивное именование, я знаю, lol .
Subject
- Подписчик получит только опубликованные значения после того, как подписка будет сделана.BehaviorSubject
- Новые подписчики получают последнее опубликованное значение ИЛИ начальное значение сразу после подписки.ReplaySubject
- Новые подписчики получают все ранее опубликованные значения сразу после подпискиисточник
В этом примере вот результат, который будет напечатан в консоли:
Вот пример использования субъектов воспроизведения, где
buffer of 2 previous values
сохраняются и отправляются новые подписки:Вот что это дает нам на консоли:
И результат:
Ссылка: https://alligator.io/rxjs/subjects/
источник
Из книги Рэндалла Кутника «Создавайте реактивные веб-сайты с помощью RxJS». :
Предмет является объектом, это турбированный наблюдаемым. По своей сути субъект действует так же, как обычный наблюдаемый объект, но каждая подписка привязана к одному и тому же источнику. Субъекты также являются наблюдателями и имеют методы next, error и done для одновременной отправки данных всем подписчикам. Поскольку субъекты являются наблюдателями, их можно передать непосредственно в вызов подписки, и все события из исходного наблюдаемого будут отправлены через субъект его подписчикам.
Мы можем использовать ReplaySubject для отслеживания истории. ReplaySubject записывает последние события и п palys их обратно к каждому новому абоненту. Например, в приложении чата. Мы можем использовать его для отслеживания предыдущей истории чата.
BehaviorSubject представляет собой упрощенную версию ReplaySubject . ReplaySubject хранить произвольное количество событий, BehaviorSubject только записывает значение последнего события. Каждый раз, когда BehaviorSubject записывает новую подписку, он передает подписчику самое последнее значение, а также любые новые значения, которые передаются. BehaviorSubject полезен при работе с отдельными единицами состояния, такими как параметры конфигурации.
источник
Самый популярный ответ явно неверен, утверждая, что:
"Если вы инициализируете a
ReplaySubject
с размером буфера 1, тогда он фактически ведет себя так же, какBehaviorSubject
"Это не совсем так; проверьте это отличное сообщение в блоге о различиях между этими двумя. Например, если вы подпишетесь на завершенный
BehaviorSubject
, вы не получите последнее значение, но для aReplaySubject(1)
вы получите последнее значение.Это важное отличие, которое нельзя упускать из виду:
Проверьте этот пример кода здесь , который исходит от другого великого блоге на эту тему.
источник
источник