Я экспериментирую с реактивными расширениями на разных платформах, и одна вещь, которая меня раздражает, - это глюки.Обходные пути для сбоев RX?
Несмотря на то, что для кода пользовательского интерфейса эти сбои могут быть not be that problematic, и обычно можно найти оператора, который работает вокруг них, я все еще считаю, что отладочный код сложнее при наличии сбоев: промежуточные результаты не важны для отладки, но мой ум не знает, когда результат является промежуточным или «окончательным».
Проработав немного с использованием функциональных FRP в Haskell и синхронных системах передачи данных, он также «чувствует» неправильно, но это, конечно, субъективно.
Но при подключении RX к приводам, отличным от UI (например, двигателям или переключателям), я думаю, что глюки более проблематичны. Как убедиться, что на внешние исполнительные механизмы отправлено только правильное значение?
Возможно, это может быть решено каким-то «диспетчером», который знает, когда какой-то «внешний датчик» инициировал инициирующее событие, чтобы все внутренние события обрабатывались до перенаправления конечного результата (результатов) на исполнительные механизмы. Что-то вроде описанного в flapjax paper.
вопрос (ы) Я надеюсь получить ответы на следующие:
- Есть ли что-то в RX, что делает фиксирующих глюки для синхронных уведомлений невозможно?
- Если нет, то для RX существует (желательно качество продукции) библиотека или подход, который фиксирует синхронные сбои? Особенно для однопоточного Javascript это может иметь смысл?
- Если общее решение не существует, как RX будет использоваться для управления внешними датчиками/исполнительными механизмами без сбоев на приводах?
Позвольте мне привести пример
Предположим, я хочу, чтобы напечатать последовательность кортежей (a,b)
где контракт
a=n b=10 * floor(n/10)
п натуральное число поток = 0,1,2 .. ..
Поэтому я ожидаю следующую последовательность
(a=0, b=0)
(a=1, b=0)
(a=2, b=0)
...
(a=9, b=0)
(a=10, b=10)
(a=11, b=10)
...
В RX, чтобы сделать более интересным, я буду использовать фильтр для вычисления потока б
var n = Observable
.Interval(TimeSpan.FromSeconds(1))
.Publish()
.RefCount();
var a = n.Select(t => "a=" + t);
var b = n.Where(t => t % 10 == 0)
.Select(t => "b=" + t);
var ab = a.CombineLatest(b, Tuple.Create);
ab.Subscribe(Console.WriteLine);
Это дает то, что я верил, что глюк (временное нарушение инварианта/контракта):
(a=0, b=0)
(a=1, b=0)
(a=2, b=0)
...
(a=10, b=0) <-- glitch?
(a=10, b=10)
(a=11, b=10)
Я понимаю, что это правильное поведение CombineLatest, но я также думал, что это называется глюком, потому что в реальной чистой системе FRP вы не получаете эти промежуточные-инвариантные результаты.
Обратите внимание, что в этом примере я не смог бы использовать Zip, а также WithLatestFrom дал бы неправильный результат.
Конечно, я мог бы просто упростить этот пример в одно монадическое вычисление, никогда не добавляя несколько потоков в поток (это будет означать, что вы не можете фильтровать, а просто карту), но это не главное: IMO в RX всегда получить «глюк», когда вы расколоть и воссоединиться наблюдаемый поток:
s
/\
a b
\/
t
Например, в Flapjax вы не получите эти проблемы.
Есть ли в этом смысл?
спасибо, Peter
Нет глюка. Пример, связанный с отображением фактического вывода 'a0 ----- (b0b1) (c1c4) (d4d9) (e9e16)' в сравнении с желаемым выходом 'a0 ----- b1 ---- c4 ---- d9 ---- e16 --- 'неправильно. Фактический вывод правильный для этого запроса. Это не сбой - это правильное функционирование этого запроса. Вам действительно нужно создать некоторые [mcve], показывая фактические сбои, чтобы мы могли ответить вам. – Enigmativity
Mea culpa, у меня создалось впечатление, что CombineLatest * всегда * вызывает сбои, как только любой из его входов поступает из одного источника. – Ziriax
Совсем нет. Вы должны ожидать, что 'CombineLatest' будет работать детерминированным способом. Невозможно справиться с «мгновенными» изменениями стоимости. Источники должны генерировать значения последовательно - один абонент должен получить значение сначала, а второй - так, если два значения ** теоретически ** означают изменение в одном и том же экземпляре, они ** не делают ** это в вычислительной реальности , Это не может быть иначе. Это особенно верно, поскольку каждый наблюдаемый источник и оператор - черные ящики. Невозможно заглянуть внутрь и посмотреть, что он должен «теоретически» делать. – Enigmativity