作为一项练习,我正在尝试构建 2 个相互更新的依赖流。
测试应用程序只是一个“英寸 <-> 厘米”转换器,两个输入均可编辑。
我遇到的问题是我无法理解如何停止导致一个字段更改的递归。
为了更好地解释这个问题,让我们看一下代码的相关部分:
var cmValue = new Rx.BehaviorSubject(0),
inValue = new Rx.BehaviorSubject(0);
# handler #1
cmValue.distinctUntilChanged().subscribe(function(v) {
inValue.onNext(cmToIn(v));
});
# handler #2
inValue.distinctUntilChanged().subscribe(function (v) {
cmValue.onNext(inToCm(v));
});
所以我们定义了 Subjects 每个都持有当前对应的值。
现在想象我们将英寸值更改为2
(使用inValue.onNext(2);
或通过键盘)。
接下来会发生什么 - 处理程序 #2 被触发并调用相应的以厘米为单位的值的重新计算。结果cmValue.onNext(0.7874015748031495)
。
这个调用实际上由处理程序#1 处理,并使用0.7874015748031495 * 2.54
导致另一个inValue.onNext(1.99999999999999973)
调用的公式重新计算以英寸为单位的值(我们手动输入的值)。
幸运的是 - 由于 FP 舍入误差,我们停止了。但在其他情况下,这可能会导致更多循环甚至无限递归。
如您所见-我部分解决了应用问题,该问题.distinctUntilChanged()
至少可以保护我们免受任何更改的无限递归,但正如我们所见-在这种情况下,它并不能完全解决问题,因为值不相同(由于 FP 操作自然)。
所以问题是:如何实现一个根本不会导致自递归的通用双向绑定?
我强调通用是为了说明使用.select()
四舍五入将是这个特定问题的部分解决方案,而不是通用的(我和其他所有人都喜欢)。
完整代码和演示:http: //jsfiddle.net/ewr67eLr/