Экспоненциальное время и несогласованные переходные значения при нажатии значения в реактивном программировании?

Я довольно новичок в реактивном программировании, и я начинаю играть с kefirjs. На первый взгляд это выглядит так, как будто потоки событий и свойства бекона/ кефира по сути представляют собой способ выразить зависание / вычисление, которое меняется со временем, и есть аккуратные способы привязки этих препятствий к событиям DOM и пользовательскому интерфейсу. Окей, звучит хорошо.

Я знаю, что в целом, когда у вас есть ошибка вычислений, если вы измените значение одного узла восходящего потока и наивно рекурсивно продвинете вычисление вниз по потоку, хорошо известны следующие проблемы:

  1. это занимает экспоненциальное время относительно числа затронутых узлов dag

  2. промежуточные вычисления используют сочетание предыдущих и текущих значений входного узла, что приводит к странным / противоречивым переходным выходным значениям.

Из игр с некоторыми простыми игрушечными программами я вижу, что кефир делает такие обновления наивно, поэтому (1.) и (2.) действительно происходят. (Я не пробовал бекон.)

Разве это не считается проблемой?

Например, в следующей программе я ожидаю, что выходной x6 изменится напрямую с 64 на 640, при стоимости 12 оценок комбинатора (6 изначально и 6 при одном обновлении). Вместо этого выходные данные идут 64,73,82,91,...,622,631,640 (63 бессмысленных промежуточных значения) за счет 132 оценок комбинатора (первоначально 6, что имеет смысл, а затем 126 для обновления, которое является чрезмерным),

https://codepen.io/donhatch/pen/EXYqBM/?editors=0010

// Basic plus
//let plus = (a,b)=>a+b;

// More chatty plus
let count = 0;
let plus = (a,b)=>{console.log(a+"+"+b+"="+(a+b)+"  count="+(++count)); return a+b;};

let x0 = Kefir.sequentially(100, [1,10]).toProperty();
let x1 = Kefir.combine([x0,x0], plus).toProperty();
let x2 = Kefir.combine([x1,x1], plus).toProperty();
let x3 = Kefir.combine([x2,x2], plus).toProperty();
let x4 = Kefir.combine([x3,x3], plus).toProperty();
let x5 = Kefir.combine([x4,x4], plus).toProperty();
let x6 = Kefir.combine([x5,x5], plus).toProperty();
x6.log('                x6');

Я весьма озадачен тем, что кефир, по-видимому, не предпринимает попыток эффективно делать такие обновления; Я думаю, что это сделало бы это не стартером для реальных приложений.

Может быть, я неправильно понимаю, для чего используется реактивное программирование. Всегда ли деревья, встречающиеся в реальных реактивных приложениях, являются деревьями или как?

1 ответ

Решение

Bacon.js имеет атомные обновления ( https://github.com/baconjs/bacon.js/), а кефир - нет. Вот почему с Bacon.js вы увидите желаемое поведение, а с кефиром вы получите много промежуточных значений.

Другие вопросы по тегам