Горячие и холодные наблюдаемые: существуют ли "горячие" и "холодные" операторы?


я рассмотрел следующий вопрос 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 51

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. Так что жарко. Вы можете увидеть это в исходном коде оператора здесь и здесь - создан наблюдаемый is shared независимо от того, каково имя события или источник.