BehaviorSubject - это тип субъекта, субъект - это особый тип наблюдаемых, поэтому вы можете подписываться на сообщения, как и любые другие наблюдаемые. Уникальные особенности BehaviorSubject:
- Ему нужно начальное значение, поскольку оно всегда должно возвращать значение в подписке, даже если оно не получило
next()
- При подписке возвращает последнее значение темы. Обычная наблюдаемая срабатывает только тогда, когда она получает
onnext
- в любой момент вы можете извлечь последнее значение субъекта в ненаблюдаемом коде, используя
getValue()
метод.
Уникальные особенности предмета по сравнению с наблюдаемым:
- Это наблюдатель в дополнение к тому, что он является наблюдаемым, поэтому вы также можете отправлять значения субъекту в дополнение к подписке на него.
Кроме того, вы можете получить наблюдаемое от субъекта поведения, используя asObservable()
метод on BehaviorSubject
.
Observable является универсальным и BehaviorSubject
технически является подтипом Observable, потому что BehaviorSubject является наблюдаемым с определенными качествами.
Пример с BehaviorSubject :
// Behavior Subject
// a is an initial value. if there is a subscription
// after this, it would get "a" value immediately
let bSubject = new BehaviorSubject("a");
bSubject.next("b");
bSubject.subscribe(value => {
console.log("Subscription got", value); // Subscription got b,
// ^ This would not happen
// for a generic observable
// or generic subject by default
});
bSubject.next("c"); // Subscription got c
bSubject.next("d"); // Subscription got d
Пример 2 с обычной темой:
// Regular Subject
let subject = new Subject();
subject.next("b");
subject.subscribe(value => {
console.log("Subscription got", value); // Subscription wont get
// anything at this point
});
subject.next("c"); // Subscription got c
subject.next("d"); // Subscription got d
Наблюдаемая может быть создана как из, так Subject
и из BehaviorSubject
использования subject.asObservable()
.
Единственная разница в том, что вы не можете отправлять значения наблюдаемому next()
методу.
В сервисах Angular я бы использовал BehaviorSubject
службу данных, так как служба Angular часто инициализируется до того, как компонент и субъект поведения гарантируют, что компонент, использующий сервис, получит последние обновленные данные, даже если нет новых обновлений с момента подписки компонента на эти данные.
Наблюдаемые: разные результаты для каждого наблюдателя
Одно очень очень важное отличие. Поскольку Observable - это просто функция, у него нет состояния, поэтому для каждого нового Observer он снова и снова выполняет наблюдаемый код создания. Это приводит к:
Это вызывает серьезные ошибки и неэффективность
BehaviorSubject (или Subject) хранит данные наблюдателя, запускает код только один раз и выдает результат всем наблюдателям.
Пример:
JSBin: http://jsbin.com/qowulet/edit?js,console
Вывод :
Наблюдайте, как использование
Observable.create
создало разные выходные данные для каждого наблюдателя, ноBehaviorSubject
дало одинаковые выходные данные для всех наблюдателей. Это важно.Другие различия суммированы.
источник
KnockoutJS's ko.observable()
, сразу увидит больше параллелей поRx.BehaviorSubject
сравнению сRx.Observable
Наблюдаемый и субъект оба являются наблюдаемыми средствами, которые наблюдатель может отслеживать. но оба они имеют некоторые уникальные характеристики. Далее есть всего 3 типа предметов, каждый из которых снова имеет уникальные характеристики. Давайте попробуем понять каждого из них.
Вы можете найти практический пример здесь на stackblitz . (Вам нужно проверить консоль, чтобы увидеть фактический вывод)
Observables
Они холодные: код выполняется, когда у них есть хотя бы один наблюдатель.
Создает копию данных: Observable создает копию данных для каждого наблюдателя.
Однонаправленный: наблюдатель не может присвоить значение наблюдаемому (источник / мастер).
Subject
Они горячие: код выполняется и значение транслируется, даже если нет наблюдателя.
Данные об акциях: одни и те же данные передаются всем наблюдателям.
двунаправленный: наблюдатель может присвоить значение наблюдаемому (источник / мастер).
Если вы используете использование темы, то вы пропустите все значения, которые транслируются до создания наблюдателя. Так что вот идет Replay Subject
ReplaySubject
Они горячие: код выполняется и значение транслируется, даже если нет наблюдателя.
Данные об акциях: одни и те же данные передаются всем наблюдателям.
двунаправленный: наблюдатель может присвоить значение наблюдаемому (источник / мастер). плюс
Воспроизведение потока сообщений. Независимо от того, когда вы подпишитесь на тему воспроизведения, вы будете получать все передаваемые сообщения.
В теме и воспроизведении темы вы не можете установить начальное значение на наблюдаемое. Итак, здесь идет Поведенческий предмет
BehaviorSubject
Они горячие: код выполняется и значение транслируется, даже если нет наблюдателя.
Данные об акциях: одни и те же данные передаются всем наблюдателям.
двунаправленный: наблюдатель может присвоить значение наблюдаемому (источник / мастер). плюс
Воспроизведение потока сообщений. Независимо от того, когда вы подпишитесь на тему воспроизведения, вы будете получать все передаваемые сообщения.
Вы можете установить начальное значение: Вы можете инициализировать наблюдаемое значение по умолчанию.
источник
ReplaySubject
имеет историю и может передавать / излучать последовательность (старых) значений. Только когда буфер установлен в 1, он ведет себя подобно aBehaviorSubject
.Объект Observable представляет коллекцию на основе push.
Интерфейсы Observer и Observable предоставляют обобщенный механизм для push-уведомлений, также известный как шаблон проектирования наблюдателя. Объект Observable представляет объект, который отправляет уведомления (поставщик); объект Observer представляет класс, который их получает (наблюдатель).
Класс Subject наследует и Observable, и Observer в том смысле, что он является и наблюдателем, и наблюдаемым. Вы можете использовать тему, чтобы подписать всех наблюдателей, а затем подписать тему на внутренний источник данных.
Подробнее на https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md
источник
Одна вещь, которую я не вижу в примерах, это то, что когда вы приводите BehaviorSubject к Observable через asObservable, он наследует поведение возврата последнего значения в подписке.
Это хитрый момент, поскольку библиотеки часто выставляют поля как наблюдаемые (то есть параметры в ActivatedRoute в Angular2), но могут использовать Subject или BehaviorSubject за кулисами. То, что они используют, повлияет на поведение подписки.
Смотрите здесь http://jsbin.com/ziquxapubo/edit?html,js,console
источник
Наблюдаемые позволяет подписаться только в то время как субъект позволяет как публиковать и подписаться.
Таким образом, субъект позволяет использовать ваши услуги как издателя, так и подписчика.
На данный момент я не очень хорош в этом,
Observable
поэтому я поделюсь только примеромSubject
.Давайте лучше разберемся с примером Angular CLI . Запустите следующие команды:
Заменить содержание на
app.component.html
:Запустите команду
ng g c components/home
для генерации домашнего компонента. Заменить содержание наhome.component.html
:#message
здесь локальная переменная Добавьте свойствоmessage: string;
вapp.component.ts
класс.Запустите эту команду
ng g s service/message
. Это создаст сервис вsrc\app\service\message.service.ts
. Предоставьте эту услугу приложению .Импорт
Subject
вMessageService
. Добавьте тему тоже. Окончательный код должен выглядеть так:Теперь внедрите этот сервис
home.component.ts
и передайте его экземпляр конструктору. Сделай этоapp.component.ts
тоже. Используйте этот экземпляр сервиса для передачи значения#message
функции сервисаsetMessage
:Внутри
app.component.ts
подпишитесь и отмените подписку (для предотвращения утечек памяти) наSubject
:Вот и все.
Теперь, любое значение , введенные внутри
#message
изhome.component.html
распечатываются на{{message}}
внутреннийapp.component.html
источник
app.component.ts
behaviour.service.ts
custom.component.ts
источник
BehaviorSubject vs Observable : RxJS имеет наблюдателей и наблюдаемых, Rxjs предлагает несколько классов для использования с потоками данных, и один из них - BehaviorSubject.
Observables : Observables - это ленивые коллекции нескольких значений с течением времени.
BehaviorSubject : субъект, которому требуется начальное значение и который выдает текущее значение новым подписчикам.
источник
Думайте о наблюдаемых как о трубе с проточной водой, иногда вода течет, а иногда нет. В некоторых случаях вам может фактически понадобиться труба, в которой всегда есть вода, вы можете сделать это, создав специальную трубу, которая всегда содержит воду, независимо от того, насколько она мала, давайте назовем эту специальную трубу BehaviorSubject , если вы оказались Поставщик водоснабжения в вашем районе, вы можете спокойно спать по ночам, зная, что только что установленная трубка просто работает.
С технической точки зрения: вы можете столкнуться с сценариями использования, где Observable всегда должен иметь значение, возможно, вы захотите зафиксировать значение входного текста с течением времени, затем вы можете создать экземпляр BehaviorSubject для обеспечения такого поведения, например:
Затем вы можете использовать «значение» для выборки изменений во времени.
Это пригодится, когда вы объедините Observables позже, взглянув на тип вашего потока как BehaviorSubject, и вы сможете убедиться, что поток хотя бы один раз запускается или сигнализирует хотя бы один раз .
источник