术语:功能反应编程/ RX中的"故障"是什么?

jhe*_*dus 13 terminology reactive-programming system.reactive rx-java reactfx

在功能反应式编程的上下文中,"毛刺"的定义是什么?

我知道在一些FRP框架中可能会发生"故障",而在其他框架中则不会.例如,RX不是无干扰,而ReactFX是无干扰的[ 1 ].

有人可以给出一个非常简单的例子,演示如何以及何时使用RX时出现毛刺,并在同一示例中显示相应的ReactFX解决方案如何以及为何无故障.

谢谢阅读.

Tom*_*ula 19

定义

我最喜欢的定义:

一个毛刺是在观察到的状态的暂时不一致.

Scala.Rx的定义:

在FRP的上下文中,故障是数据流图中的临时不一致.由于更新不是即时发生的,而是花费时间进行计算,因此在更新过程中FRP系统内的值可能暂时不同步.此外,根据FRP系统的性质,可以在传播中对节点进行多次更新.

考虑整型变量a,b.定义sumprod这样
sum := a + b,
prod := a * b.

让我们将此示例重写为JavaFX:

IntegerProperty a = new SimpleIntegerProperty();
IntegerProperty b = new SimpleIntegerProperty();
NumberBinding sum = a.add(b);
NumberBinding prod = a.multiply(b);
Run Code Online (Sandbox Code Playgroud)

现在让我们写一点一致性检查:

InvalidationListener consistencyCheck = obs -> {
    assert sum.intValue() == a.get() + b.get();
    assert prod.intValue() == a.get() * b.get();
};

sum.addListener(consistencyCheck);
prod.addListener(consistencyCheck);

a.set(1);
b.set(2);
Run Code Online (Sandbox Code Playgroud)

此代码失败,最后一行出现断言错误,因为:

  • b 已更新(至2)
    • sum 更新(至3)
      • `consistencyCheck`被触发,`a == 1`,`b == 2`,但`prod == 0`,因为`prod`尚未更新

这是一个小问题 - prod暂时与a和不一致b.

使用ReactFX消除毛刺

首先请注意ReactFX 不是开箱即用的"无故障",但它为您提供了消除故障的工具.除非你有意识地使用它们,否则ReactFX并不比RX(例如rxJava)更无故障.

消除ReactFX中的毛刺的技术依赖于事件传播是同步的事实.另一方面,RX中的事件传播总是异步的,因此这些技术不能在RX系统中实现.

在上面的例子中,我们想推迟听众通知,直到双方sumprod已更新.这是使用ReactFX实现此目的的方法:

import org.reactfx.Guardian;
import org.reactfx.inhibeans.binding.Binding;

IntegerProperty a = new SimpleIntegerProperty();
IntegerProperty b = new SimpleIntegerProperty();
Binding<Number> sum = Binding.wrap(a.add(b)); // Binding imported from ReactFX
Binding<Number> prod = Binding.wrap(a.multiply(b)); // Binding imported from ReactFX

InvalidationListener consistencyCheck = obs -> {
    assert sum.getValue().intValue() == a.get() + b.get();
    assert prod.getValue().intValue() == a.get() * b.get();
};

sum.addListener(consistencyCheck);
prod.addListener(consistencyCheck);

// defer sum and prod listeners until the end of the block
Guardian.combine(sum, prod).guardWhile(() -> {
    a.set(1);
    b.set(2);
});
Run Code Online (Sandbox Code Playgroud)