Комментарии 8
Проблема, озвученная в заголовке понятна, но примеры по-моему выбраны не совсем удачно.
Температура она что в фаренгейтах, что в кельвинах обозначает буквально одно и то же физическое состояние. Модель старается выразить эту идею. Но пытается ее смоделировать каким-то замороченным способом - в виде двух отдельных свойств-состояний с квантовой запутанностью рекурсивными зависимостями между ними. Разработчику стало скучно и он решил поднасыпать себе сложностей на ровном месте?
В итоге вы приходите к решению с одним source вместо двух, что логично - температура же одна. Но выбранная архитектура продолжает играть против вас. Количество условных ветвлений в каждой строчке буквально кричит об этом своей избыточностью для такой простой задачи. Хорошо, что фреймворк и язык здесь помогают срезать углы, просто насколько этого хватит?
Попробуйте добавить поддержку ещё одной единицы измерения - кельвинов - и посмотрите в каких местах будет двигаться код. А конвертор для сотни валют получится сделать так же?
Например, можно требовать при создании состояния, чтобы все его зависимости уже существовали. Обычно так делают push-библиотеки типа RxJS или Effector.
В эффекторе связи принято создавать через sample(), т.е. в любой момент после создания сущностей и таким образом можно сущность даже саму на себя зациклить:
sample({
source: $source,
fn: (...) => { ... },
target: $source
});Действительно, зря я его там добавил. А при зацикливании на себя он в бесконечную рекурсию уходит или отрабатывает 1 раз и засыпает?
Зависит от того, что в функции маппинга и что передано в source/target. Если значения после мапа получаются не эквивалентные, то будет бесконечный цикл. Известная проблема, но авторы эффектора считают ее нерешаемой.
fahrenheit( fahrenheit )
Это оочень странный и крайне дурной api. Принимать фаренгейты для конвертации в фаренгейты, заодно конструировать фаренгейты пока конвертируешь в фаренгейты. Симметричнаяя структура и для цельсиев. Зачем там вообще ухищрения с кучей полей в разных метриках да ещё и кэшируемые? Казалось бы оставь какое-нибудь одно поле и кэшируй второе вычислимое поле. Сделай адекватный конструктор, а лучше два, чтобы точно знать какое из значений подаётся на вход и будет тебе счастье.
Использование одного из двух каналов в качестве источника истины штука рабочая, но не всегда применимая. В частности, из-за двойного округления будет получаться так, что записываешь одно значение фаренгейтов, а читаешь другое.

Циклические реактивные зависимости