В чем разница между наблюдаемым и субъектом в rxjs?

я просматривал этот блог и читал об Observables и не мог понять разницу между Observable и Subject

Ответ 1

В потоковом программировании есть два основных интерфейса: Observable и Observer.

Наблюдаемое для потребителя, оно может быть преобразовано и подписано:

observable.map(x => ...).filter(x => ...).subscribe(x => ...)

Observer - это интерфейс, который используется для подачи наблюдаемого источника:

observer.next(newItem)

Мы можем создать новый Observable с помощью Observer:

var observable = Observable.create(observer => { 
    observer.next('first'); 
    observer.next('second'); 
    ... 
});
observable.map(x => ...).filter(x => ...).subscribe(x => ...)

Или мы можем использовать объект Subject, который реализует интерфейсы Observable и Observer:

var source = new Subject();
source.map(x => ...).filter(x => ...).subscribe(x => ...)
source.next('first')
source.next('second')

Ответ 2

Смотрите документ rxjs (больше информации и примеров там): http://reactivex.io/rxjs/manual/overview.html#subject

Что такое предмет? Субъект RxJS - это специальный тип Observable, который позволяет многоадресно передавать значения многим наблюдателям. В то время как обычные Observables являются одноадресными (каждый подписанный Observer имеет независимое выполнение Observable), объекты являются многоадресными.

Субъект похож на Observable, но может передавать многоадресные сообщения многим наблюдателям. Темы похожи на EventEmitters: они поддерживают реестр многих слушателей.

и код, Subject, расширяющий Observable: https://github.com/ReactiveX/rxjs/blob/master/src/internal/Subject.ts#L22

/**
 * @class Subject<T>
 */
export class Subject<T> extends Observable<T> implements SubscriptionLike {
//...
}

Ответ 3

С другой стороны, хорошо отметить, что подписка на Observable повторно выполняет функцию Observable. Это может привести к проблемам с производительностью, если источником данных является, например, служба.

Если вы хотите, чтобы несколько подписчиков получили одно и то же значение, вам может потребоваться тема. Для этого убедитесь, что ваша подписка установлена до того, как субъект подписался на источник данных. В противном случае ваш процесс застрянет.

Более подробная информация здесь: https://javascript.tutorialhorizon.com/2017/03/23/rxjs-subject-vs-observable/

Ответ 4

Наблюдаемый может сообщить только одному наблюдателю, в то время как Субъект может сообщить нескольким наблюдателям.

Ответ 5

Наблюдаемые

  1. Они холодные: код выполняется, когда у них есть хотя бы один наблюдатель.

  2. Создает копию данных: Observable создает копию данных для каждого наблюдателя.

  3. Однонаправленный: Наблюдатель не может присвоить значение наблюдаемому (происхождение/мастер).

  4. Код будет работать для каждого наблюдателя. Если это HTTP-вызов, он вызывается для каждого наблюдателя.

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

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

Тема

  1. Они горячие: код выполняется, а значение транслируется, даже если нет наблюдателя.

  2. Данные об акциях: одни и те же данные передаются всем наблюдателям.

  3. двунаправленный: наблюдатель может присвоить значение наблюдаемому (источник/мастер).

  4. Если вы используете использование темы, то вы пропустите все значения, которые транслируются до создания наблюдателя. Итак, вот вам тема повторов

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

Ответ 6

Представьте, что у вас есть поток данных, поступающий в ваше приложение, как при соединении через веб-сокет. Вы хотите способ справиться с этим. Есть несколько решений:

1. обычный запрос ajax:   Это решение не является жизнеспособным, потому что оно   не применимо для обработки push-данных. Это больше тяга, чем   От себя.

2. Обещание:   Также не хорошо, потому что вы должны вызвать их и   они могут получить только один раз. Также больше тяги, чем толчка.

Таким образом, чтобы получить эти данные, в старое время мы проводим длинный опрос. Именно здесь мы устанавливаем функцию интервала для извлечения этого потока данных каждую 1 минуту для примера. Хотя это работает, но на самом деле это отягощает такие ресурсы, как процессор и память.

Но теперь с вариантом № 3,

3. Наблюдаемый: Вы можете подписаться и позволить потоку данных прийти   без остановки, пока не будет вызвана функция complete.

Круто верно? Но тогда возникает другая проблема. Что делать, если вы хотите наблюдать входящие данные только один раз где-то в вашем приложении. Но вы хотите использовать эти данные одновременно с вашим приложением, когда они поступят. Это когда и где вы используете тему. Вы размещаете subject.subscribe() в местах, которые вы хотите использовать в приложении. Когда данные поступят, места, где есть subject.subscribe(), будут обрабатывать их одновременно. Но наблюдатель должен подписаться на эту тему в качестве аргумента следующим образом.

observer.subscribe(subject).

Пример приложения - это когда вы хотите создать уведомление.

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

Другая аналогия - через подписку на журналы. Каждый подписчик получит журнал со своим именем на нем. Таким образом, другая подписка = другое имя получателя. (Обычная наблюдаемая) Но когда вы делитесь со своими друзьями, все ваши друзья получат один и тот же журнал, на котором будет только ваше имя (обычно можно наблюдать с помощью темы)

Этот парень очень хорошо объясняет это на примере кода. Вы можете проверить это на https://javascript.tutorialhorizon.com/2017/03/23/rxjs-subject-vs-observable/

Надеюсь, этот ответ поможет.