Вы определили горячие и холодные наблюдаемые.
Observable.range
возвращает холодный наблюдаемый объект, хотя вы описываете результирующие запросы в иерархии, как будто они горячие; то есть, как если бы они разделяли побочные эффекты подписки. Они не. Каждый раз, когда вы подписываетесь на наблюдаемый объект cold, это может вызвать побочные эффекты. В вашем случае каждый раз, когда вы подписываетесь на range
(или на запросы, установленные на range
), он генерирует диапазон значений.
Во втором пункте вашего исследования вы определили, как преобразовать холодную наблюдаемую в горячую наблюдаемую; а именно, используя Субъекты. (Хотя в .NET вы не используете Subject<T>
напрямую; вместо этого вы должны использовать такой оператор, как Publish. Я подозреваю, что в RxJava есть аналогичный оператор, и я бы рекомендовал его использовать.)
Дополнительная информация
Определение горячего в моей интерпретации, как подробно описано в моем сообщении в блоге, указанном выше, - это когда наблюдаемый объект не вызывает никаких побочных эффектов подписки. (Обратите внимание, что горячий наблюдаемый может многоадресно передавать побочные эффекты соединения при преобразовании из холодного в горячий, но температура относится только к к склонности наблюдаемого объекта вызывать побочные эффекты подписки, потому что это все, о чем мы действительно заботимся, когда говорим о температуре наблюдаемого на практике.)
Оператор map
(Select
в .NET, упомянутый в заключении моего сообщения в блоге) возвращает наблюдаемое, которое наследует температуру своего источника, поэтому на нижней диаграмме c
, a
и b
равны холодно, потому что d
холодно. Если гипотетически вы примените publish
к d
, то c
, a
и b
унаследуют температуру hot от опубликованного наблюдаемого, а это означает, что подписка на них не вызовет побочных эффектов подписки. Таким образом, публикация d
преобразует холодную наблюдаемую, а именно range
, в горячую наблюдаемую.
.--> c --> a
d --|
.--> c --> b
Однако ваш вопрос был о том, как разделить вычисление c
, а также d
. Даже если вы опубликуете d
, c
все равно будет пересчитываться как для a
, так и для b
для каждого уведомления от d
. Вместо этого вы хотите поделиться результатами c
между a
и b
. Я называю наблюдаемую, в которой вы хотите поделиться побочными эффектами вычислений, "активной". (Я позаимствовал этот термин из терминологии пассивный и активный, используемый в нейробиологии для описания электрохимических токов в нейронах.)
На вашей верхней диаграмме вы считаете c
активным, потому что это вызывает значительные побочные эффекты вычислений, согласно вашей собственной интерпретации. Обратите внимание, что c
активен независимо от температуры d
. Чтобы поделиться побочными эффектами вычисления активного наблюдаемого объекта, как ни странно, вы должны использовать publish
точно так же, как и для холодного наблюдаемого объекта. Это связано с тем, что технически активные вычисления являются побочными эффектами в том же смысле, что и холодные наблюдаемые, в то время как пассивные вычисления не имеют побочных эффектов, как горячие наблюдаемые. Я ограничил термины горячий и холодный, чтобы они относились только к побочным эффектам начальных вычислений, которые я называю побочными эффектами подписки< /em>, потому что люди обычно используют их именно так. Я ввел новые термины, активный и пассивный, для обозначения побочных эффектов вычислений отдельно от побочных эффектов подписки.
В результате эти термины на практике просто интуитивно смешиваются друг с другом. Если вы хотите поделиться побочными эффектами вычисления c
, просто publish
вместо d
. При этом a
и b
неявно становятся горячими, потому что map
наследует побочные эффекты подписки, как было сказано ранее. Таким образом, вы фактически делаете правую часть наблюдаемого горячей, публикуя либо d
, либо c
, но публикация c
также имеет свои побочные эффекты вычислений.
Если вы публикуете c
вместо d
, то d
остается холодным, но это не имеет значения, поскольку c
скрывает d
от a
и b
. Таким образом, публикуя c
, вы также фактически публикуете d
. Следовательно, применение publish
в любом месте вашего наблюдаемого делает правую часть наблюдаемого эффективно горячей. Неважно, где вы вводите publish
или сколько наблюдателей или конвейеров вы создаете с правой стороны наблюдаемого. Однако выбор публикации c
вместо d
также разделяет побочные эффекты вычислений c
, что технически завершает ответ на ваш вопрос. КЭД
person
Dave Sexton
schedule
26.11.2014