捉可观测量之间循环依赖(Catch circular dependency between obse

2019-10-18 07:15发布

我有一个用户编程方案,其中用户可以结束了创建依赖于彼此的两个观测。 RxJS不允许循环依赖关系,据我所看到的,内存或堆达到其极限和onError回调被触发,其值为true

如何检测循环依赖明确,并抛出一个更具描述性错误消息?

此代码演示了如何创建一个RxJS循环依赖:

 var obsA, obsB; obsA = Rx.Observable .returnValue(42) .combineLatest(obsB, function (a, b) { return a + b; }); obsB = Rx.Observable .returnValue(42) .combineLatest(obsA, function (b, a) { return b + a; }); obsA .subscribe(function (val) { console.log('onNext:' + val); }, function (err) { console.error('onError: ' + err); }, function () { console.log('onCompleted'); }); 

该错误消息简直是true

Answer 1:

在原来的问题的代码不会创建一个循环依赖。 在您指定的时间ObsAObsBundefined ,还等什么你真的做的是调用combineLatest(undefined, function ...) 所以你看到的错误是因为你传递undefinedcombinedLatest()

实际上,它需要一些努力,创造一个真正的循环依赖。 如果您使用的defer ,那么你将有一个真正的循环依赖关系:

 var obsA, obsB, aRef, bRef; aRef = Rx.Observable.defer(function () { return obsA; }); bRef = Rx.Observable.defer(function () { return obsB; }); obsA = Rx.Observable .returnValue(42) .combineLatest(bRef, function (a, b) { return a + b; }); obsB = Rx.Observable .returnValue(42) .combineLatest(aRef, function (b, a) { return b + a; }); obsA.subscribe(); 
 <script src='https://rawgit.com/Reactive-Extensions/RxJS/v.2.5.3/dist/rx.all.js'></script> 

现在是一个真正的循环依赖。 不幸的是,你仍然得到同样的错误,但有一个更深刻的堆栈跟踪:

RangeError: Maximum call stack size exceeded.
/* ... stack ... */

没有万无一失的方法来检测周期。 你可以换一个新的可观测的观测和检测到你的订阅方法递归调用。 但是,这样的算法会如果标的观测使用被打败subscribeOnpublishconcat其他任何延迟实际圆形订阅。

最好的建议,我已经是追加一个catch用于检查各种错误,并有更好的错误替换它条款:

 var obsA, obsB, aRef, bRef; aRef = Rx.Observable.defer(function () { return obsA; }); bRef = Rx.Observable.defer(function () { return obsB; }); obsA = Rx.Observable .returnValue(42) .combineLatest(bRef, function (a, b) { return a + b; }) .catch(function (e) { var isStackError = e instanceof RangeError && e.message === 'Maximum call stack size exceeded'; return Rx.Observable.throw(isStackError ? new Error('Invalid, possibly circular observables.') : e); }); obsB = Rx.Observable .returnValue(42) .combineLatest(aRef, function (b, a) { return b + a; }) .catch(function (e) { var isStackError = e instanceof RangeError && e.message === 'Maximum call stack size exceeded'; return Rx.Observable.throw(isStackError ? new Error('Invalid, possibly circular observables.') : e); }); obsA.subscribe(); 
 <script src='https://rawgit.com/Reactive-Extensions/RxJS/v.2.5.3/dist/rx.all.js'></script> 



文章来源: Catch circular dependency between observables