在函数式反应性编程中,“故障”的定义是什么?
我知道,在一些玻璃钢框架中,“小故障”可能发生,而在另一些框架中则不然。例如,RX不是无故障的,而ReactFX是无故障的[1]。
有人能给出一个非常简单的示例,演示在使用RX时如何以及何时会出现故障,并在相同的示例中展示相应的ReactFX解决方案是如何以及为什么没有故障的。
感谢您的阅读。
发布于 2014-08-05 14:24:59
定义
我(自己)最喜欢的定义:
故障是可观察状态中暂时的不一致。
来自Scala.Rx的定义
在玻璃钢的上下文中,故障是数据流图中暂时的不一致。由于更新不是即时发生的,而是需要时间来计算,玻璃钢系统中的值在更新过程中可能会瞬间不同步。此外,根据玻璃钢系统的性质,有可能使节点在传播过程中不止更新一次。
示例
考虑整数变量a,b。定义sum和prod,以便
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);现在,让我们编写一个小的一致性检查:
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);此代码在最后一行出现断言错误时失败,因为:
b被更新(到2) sum被更新为(到3) consistencyCheck被触发,a == 1,b == 2,但是prod == 0,因为prod还没有更新
这是一个小故障-- prod暂时与a和b不一致.
利用ReactFX消除故障
首先要注意的是,ReactFX并非“无故障”,但它为您提供了消除故障的工具。除非您有意识地使用它们,否则ReactFX并不比RX (例如rxJava)更无故障。
消除ReactFX故障的技术依赖于事件传播是同步的这一事实。另一方面,RX中的事件传播总是异步的,因此这些技术不能在RX系统中实现。
在上面的示例中,我们希望将侦听器通知推迟到更新了sum和prod之后。这是如何通过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);
});发布于 2015-01-27 13:49:44
简短的回答:小故障=不一致/非法/无意义的状态。
此外,另一个答案见第29分钟的钠作者的演讲:http://youtu.be/gaG3tIb3Lbk。
以及相应的SOF回答:如何避免Rx中的故障
因此,这是我的理解,什么是故障是基于托马斯的答案。
有一个数据流图,有三个节点: A,B,C
A->B
A->C
在这个简单的例子中,如果我更改A并导致更改B,就会发生故障,但是C还没有更新。这是个小故障。
C与B不一致。
说B=2*A,C=2*A。
如果B不等于C,那就是一个小故障。
发布于 2016-02-16 22:56:42
下面是C# RX中致命“故障”情况的一个非常简短的理论示例。
var t = Observable
.Interval(TimeSpan.FromSeconds(1))
.Publish()
.RefCount();
var s = t.CombineLatest(t, (t1,t2) => 1/(1-(t1-t2));由于t1和t2都代表了热门可观测t的最新值,所以人们会认为t1-t2永远是0。所以,我们应该永远是1。
但是,当订阅s时,我们确实得到了1作为第一个观测值,但随后我们得到了零例外除法。在RxJS,我们可以得到NaN。
原因很简单:a.CombineLatest(b, f)会在a或b生成一个值时做出反应,将这个新值与另一个可观测值的最后观察值结合起来。这是设计上的,但根据我的经验,使用RX的人有时会认为这些都是小故障,尤其是来自其他玻璃钢库,它们有着不同的“最新”概念。
当然,这是一个人为的例子,只是为了说明对CombineLatest的误解。
也许CombineLatest应该被称为WhenAny,就像在ReactiveUI库中一样,这会澄清操作语义吗?
https://stackoverflow.com/questions/25139257
复制相似问题