As an exercise I'm trying to build 2 dependent streams which update one another.The test application is simply an "Inches <-> Centimeters" converter, with both inputs editable.The issue I am experiencing is that I cannot get how can I stop recursion that causes one field change.To better explain the issue let's have a look at the relevant part of code:var cmValue = new Rx.BehaviorSubject(0), inValue = new Rx.BehaviorSubject(0);# handler #1cmValue.distinctUntilChanged().subscribe(function(v) { inValue.onNext(cmToIn(v));});# handler #2inValue.distinctUntilChanged().subscribe(function (v) { cmValue.onNext(inToCm(v));});So we define to Subjects each of which holds the current corresponding value.Now imagine we change the value in inches to 2 (using inValue.onNext(2); or via keyboard).What happens next - is the handler #2 is triggered and it invokes a corresponding recalculation of a value in centimeters. Which results to cmValue.onNext(0.7874015748031495).This call in fact is then handled by handler #1 and causes the value in inches (the one we put manually) to be recalculated, using 0.7874015748031495 * 2.54 formula which causes another inValue.onNext(1.99999999999999973) call.Luckily - due to FP rounding error that's where we stop. But in other scenarios this may lead to more loops or even to an infinite recursion.As you can see - I partially solved the issue applying .distinctUntilChanged() which at least protects us from an infinite recursion on any change, but as we can see - in this case it's does not solve the problem entirely since values are not identical (due to FP operations nature).So the question is: how would one implement a generic two-way binding that does not cause self-recursion at all?I emphasized generic to make a note that using .select() with rounding would be a partial solution for this particular issue, and not the generic one (which I and everyone else would prefer).The complete code and demo: http://jsfiddle.net/ewr67eLr/ 解决方案 In your demo you have two input fields. "Keyup" events for this inputs will be the information source, and inputs value will be destination. In this case you don't need mutable states for checking updates of observables. Rx.Observable.fromEvent(cmElement, 'keyup') .map(targetValue) .distinctUntilChanged() .map(cmToIn) .startWith(0) .subscribe(function(v){ inElement.value = v; });Rx.Observable.fromEvent(inElement, 'keyup') .map(targetValue) .distinctUntilChanged() .map(inToCm) .startWith(0) .subscribe(function(v){ cmElement.value = v; });Check my example here: http://jsfiddle.net/537Lrcot/2/ 这篇关于2 个依赖流的安全更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-02 04:25