Горячие и холодные наблюдаемые: существуют ли "горячие" и "холодные" операторы?
я рассмотрел следующий вопрос SO: что такое горячие и холодные наблюдаемые?
подведем итоги:
- горячий наблюдаемый излучает значение независимо от его подписок, т. е. значения полученные наблюдателями данные являются функцией времени подписки.
тем не менее, я чувствую, что горячий против холодного все еще является источником путаницы. Итак, вот мои вопросы:
-
являются ли все наблюдаемые rx холодными по умолчанию (за исключением предметов)?
я часто читаю, что события являются типичной метафорой для горячих наблюдаемых, но я также читал, что
Rx.fromEvent(input, 'click')
является ли холод наблюдаемым(?). -
есть/чего операторы Rx, которые превращают холодные наблюдаемые в горячие наблюдаемые (кроме
publish
иshare
)?например, как это работает с оператором Rx
withLatestFrom
? Пустьcold$
быть холодным наблюдаемым, который где-то был подписан. Будетsth$.withLatestFrom(cold$,...)
горячий наблюдаемых?или если я делаю
sth1$.withLatestFrom(cold$,...), sth2$.withLatestFrom(cold$,...)
и подписаться наsth1
иsth2
, Я всегда вижу одно и то же значение для обоихsth
? я думал
Rx.fromEvent
создает холодную но это не так, как упоминалось в одном из ответов. Однако я все еще озадачен этим поведением:codepen.io/anon/pen/NqQMJR?editors=101. разные подписки получают разные значения из одного и того же наблюдаемого. Разве это неclick
событие общий?
4 ответа:
я возвращаюсь через несколько месяцев к моему первоначальному вопросу и хотел бы поделиться полученными знаниями в то же время. Я буду использовать следующий код в качестве объяснения поддержки (jsfiddle):
var ta_count = document.getElementById('ta_count'); var ta_result = document.getElementById('ta_result'); var threshold = 3; function emits ( who, who_ ) {return function ( x ) { who.innerHTML = [who.innerHTML, who_ + " emits " + JSON.stringify(x)].join("\n"); };} var messages$ = Rx.Observable.create(function (observer){ var count= 0; setInterval(function(){ observer.onNext(++count); }, 1000) }) .do(emits(ta_count, 'count')) .map(function(count){return count < threshold}) .do(emits(ta_result, 'result')) messages$.subscribe(function(){});
как упоминалось в одном из ответов, определение наблюдаемого приводит к серии обратных вызовов и регистрации параметров. Поток данных должен быть запущен, и это делается через
ваше резюме и связанный с ним вопрос верны, я думаю, что терминология может вас смутить. Я предлагаю вам рассматривать горячие и холодные наблюдаемые как активные и пассивные наблюдаемые (соответственно).
то есть активный (горячий) наблюдаемый будет излучать элементы, независимо от того, подписался ли кто-то или нет. Канонический пример, опять же, Нажмите кнопку события происходят ли кто-то слушает их или нет. Это различие важно, потому что если, например, я нажимаю на кнопка, а затем Подписаться на нажатия кнопок (в этом порядке), я не буду видеть кнопку нажмите, что уже произошло.
пассивный (холодный) наблюдаемый будет ждать, пока абонент не существует, прежде чем испускать элементы. Представьте себе кнопку, где вы не можете нажать на нее, пока кто-то не прослушивает события-это гарантирует, что вы всегда видите каждое событие щелчка.
все наблюдаемые Rx "холодные" (или пассивные) по умолчанию? Нет,
Rx.fromEvent(input, 'click')
например горячий (или активный) заметный.я тоже это читал
Rx.fromEvent(input, 'click')
холодный наблюдаемых(?)это не так.
существуют ли операторы Rx, которые превращают холодный наблюдаемый в горячий наблюдаемый?
концепция превращения горячего (активного) наблюдаемого в холодный (пассивный) наблюдаемый заключается в следующем: вам нужно записывать события, которые происходят, пока ничего не подписано, и предлагать эти элементы (различными способами) подписчикам это придет в будущем. Один из способов сделать это-использовать теме. Например, вы можете использовать
ReplaySubject
для буферизации испускаемых элементов и их воспроизведения будущим подписчикам.два оператора, которые вы назвали (
publish
иshare
) как использовать предметы внутренне, чтобы предложить эту функциональность.как это работает с оператором Rx
withLatestFrom
? Пустьcold$
быть холодным наблюдаемым, который был подписан. Будетsomething$.withLatestFrom(cold$,...)
горячий наблюдаемых?если
something
является горячим наблюдаемым, тогда да. Еслиsomething
является холодным наблюдаемым, то нет. Возвращаясь к примеру событий, еслиsomething
- это поток событий click кнопок:var clickWith3 = Rx.fromEvent(input, 'click') .withLatest(Rx.Observable.from([1, 2, 3]);
или если я делаю
foo$.withLatestFrom(cold$,...), bar$.withLatestFrom(cold$,...)
и подписаться наfoo
иbar
, я всегда буду видеть одни и те же значения для обоих?не всегда. Опять же, если
foo
иbar
щелчки по разным кнопкам, например, тогда вы увидите разные ценности. Также, Даже если они были одной и той же кнопкой, если ваша функция комбинации (2-й аргумент дляwithLatest
) не возвращает тот же результат для тех же входных данных, то вы не увидите те же значения (потому что он будет вызываться дважды, как описано ниже).я думал
Rx.fromEvent
создает холодные наблюдаемые, но это не так, как указано в одном из ответов. Тем не менее, я все еще озадачен этим поведением: codepen.io/anon/pen/NqQMJR?editors=101. разные подписки получают разные значения из одного и того же наблюдаемого. Разве это неclick
событие общий?я укажу вам!--63-->это великий ответ на загадочность на вопрос у меня было примерно такое же поведение. Этот ответ объяснит это намного лучше, чем я могу, но суть его заключается в том, что источник (событие click) является "общим", да, но ваши операции над ним не являются. Если вы хотите поделиться не просто нажмите событие, но и операция на нем, вам нужно будет сделать это явно.
values
в вашем codepen ленив - ничего не происходит, пока что-то не подписывается, и в этот момент он проходит и подключает его. Поэтому в вашем примере, хотя вы подписываетесь на одну и ту же переменную, она создает два разных потока; по одному для каждого вызова подписки.вы можете думать о
values
как генератор потоков дляclick
Сmap
прилагается.
.share()
в конце этой карты будет создавать поведение, которое мы ожидаем, потому что это неявная подписка.
это не ответ на все ваши вопросы (я хотел бы знать их все!) но наверняка, все
fromEvent
параметры горячие. Щелчок, похоже, не потому, что это не" непрерывное " событие, такое как mousemove, но в любом случае подписка на источник (addEventListener
илиon
вызов) выполняется только один раз, когда создается Observable. Так что жарко. Вы можете увидеть это в исходном коде оператора здесь и здесь - создан наблюдаемый isshare
d независимо от того, каково имя события или источник.