Некоторые говорят, что FRP относится к обработке потоков событий без явного управления состоянием. Этот человек, например:управляющее состояние с FRP
http://www.slideshare.net/borgesleonardo/functional-reactive-programming-in-clojurescript
Другие мотивируют FRP, указывая на трудности программирования полностью побочных эффектов, поскольку нужно делать с асинхронными.
http://cs.brown.edu/~sk/Publications/Papers/Published/mgbcgbk-flapjax/
Однако экспериментировать с FRP (Flapjax), я продолжаю ударять ту же проблему: неспособность справиться с состоянием, за исключением явно, с помощью побочных эффектов.
Например, очередь анимации. Изменения поступают в поток событий. Когда приходит первое изменение, мне нужно сделать очередную ничью в будущем (например, с помощью window.requestAnimationFrame) и организовать скопление изменений между текущим и будущим событиями. Когда происходит событие розыгрыша, мне нужно нарисовать накопленные изменения.
Это примерно шесть строк кода с использованием императивного стиля с шаблоном наблюдателя, но я не могу найти разумный способ выразить это в FRP. Единственное, что подходит близко, - это закрытие связанных потоков событий над общим состоянием и явное управление событиями состояния и рендеринга с помощью побочных эффектов. Это вряд ли улучшает настоятельные обратные вызовы.
Как это должно быть обработано в FRP?
Вот утилита Flapjax для закрытия над государством:
function worldE(init, handlers) {
var r = fj.receiverE();
fj.forEach(function(h) {
h[0].mapE(function (ev) {
r.sendEvent(init = h[1](init, ev));
});
}, handlers);
return r;
}
И здесь он используется в цикле анимации:
function initialize(opts) {
var blitE = fj.receiverE();
function accumulate(state, data) {
if (!state.queued) {
window.requestAnimationFrame(blitE.sendEvent);
}
return {queued: true, changes: _.extend({}, state.changes, data)};
}
function dodraw(state, _) {
draw(state.changes);
return {queued: false, changes: {}};
}
worldE({queued: false, changes: {}},
[[opts.data_source, accumulate], [blitE, dodraw]]);
}
вещи, чтобы отметить: это больше, менее читаемыми и менее ремонтопригодны, чем эквивалентный код обратного вызова. Он по-прежнему требует явного управления состоянием. И он действует через побочные эффекты.
Есть ли лучший способ сделать это в FRP? Другой шаблон или другая библиотека?
Я не знаком с flajax, но вы также можете попробовать RxJs. У этого может быть другой, лучший синтаксис. Кроме того, если вы хотите увидеть несколько более сложных примеров для FRP, взгляните на язык ELM http://elm-lang.org/ – allprog