我正在学习角度2和rxjs。我有3个变量,A B C。
我正在尝试设置observable,以便:当A更新时,B和C将自动更新。更新B时,C将自动更新。我尝试了两种设置,但效果不理想。
如何设置我的observables /订阅,以便在更新A时,C只会使用A和B的最新值更新一次?
编辑 - 添加的代码
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input />
&#13;
var A = new Rx.BehaviorSubject(1);
var A_Observable = A.asObservable();
var B = new Rx.BehaviorSubject(10);
var B_Observable = B.asObservable();
A_Observable.subscribe(function(A_value) {
var newB = A_value * 10;
// console.log("B auto updating to " + newB);
B.next(newB);
});
// LATEST FROM OBSERVABLE
var latestFromObservable = B_Observable.withLatestFrom(A_Observable);
latestFromObservable.subscribe(function(data) {
console.log("LATEST FROM : Value for A is " + data[1] + " ; Value for B is " + data[0]);
});
// COMBINE ALL OBSERVABLE
var combineAllObservable = Rx.Observable.combineLatest(A_Observable,B_Observable);
combineAllObservable.subscribe(function(data) {
console.log("COMBINE LATEST : Value for A is " + data[0] + " ; Value for B is " + data[1]);
});
// UPDATE TO A
setTimeout(function(){
console.log("UPDATING A");
A.next(2);
},1000);
// SATISFACTORY RESULT
setTimeout(function(){
console.log("SATISFACTORY RESULT : Value for A is 2 ; Value for B is 20 --- CALLED ONLY ONCE WITH LATEST VALUES");
},2000);
&#13;
答案 0 :(得分:0)
代码的行为方式是这样的,因为默认情况下RxJs同步运行代码。 withLatestFrom
案件的事件链:
A
值:A.next(2);
A
有两种用法:
B
- 订阅(首先出现)withLatestFrom
(排在第二位)B
- 订阅
B
B
:C
- 订阅C
- 订阅(旧值为A
!)A
中的withLatestFrom
的新值被提取但C
- 未触发订阅(因为它仅由B
更新触发)可能的解决方案是添加debounceTime(0)
。它将强制C
- 订阅在withLatestFrom
内的值已更新时异步运行。
有关RxJs Scheduler
的更多信息,请访问
var A = new Rx.BehaviorSubject(1);
var A_Observable = A.asObservable();
var B = new Rx.BehaviorSubject(10);
var B_Observable = B.asObservable();
A_Observable.subscribe(function(A_value) {
var newB = A_value * 10;
// console.log("B auto updating to " + newB);
B.next(newB);
});
// LATEST FROM OBSERVABLE
var latestFromObservable = B_Observable.debounceTime(0).withLatestFrom(A_Observable);
latestFromObservable.subscribe(function(data) {
console.log("LATEST FROM : Value for A is " + data[1] + " ; Value for B is " + data[0]);
});
// COMBINE ALL OBSERVABLE
var combineAllObservable = Rx.Observable.combineLatest(A_Observable,B_Observable).debounceTime(0);
combineAllObservable.subscribe(function(data) {
console.log("COMBINE LATEST : Value for A is " + data[0] + " ; Value for B is " + data[1]);
});
// UPDATE TO A
setTimeout(function(){
console.log("UPDATING A");
A.next(2);
},1000);
// SATISFACTORY RESULT
setTimeout(function(){
console.log("SATISFACTORY RESULT : Value for A is 2 ; Value for B is 20 --- CALLED ONLY ONCE WITH LATEST VALUES");
},2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.min.js"></script>
我想添加两件事:
withLatestFrom
方法在您的情况下更好,因为依赖关系图看起来像C -> B -> A
,当A更新时,B也会更新。如果A
和B
是独立的,那么combineLatest
将是更好的选择。Subject
B
无需debounceTime
。你可以像这样重写代码(没有var A = new Rx.BehaviorSubject(1);
var A_Observable = A.asObservable();
var B_Observable = A_Observable.map(function(A_value) {
var newB = A_value * 10;
// console.log("B auto updating to " + newB);
return newB;
});
var latestFromObservable = B_Observable.withLatestFrom(A_Observable);
latestFromObservable.subscribe(function(data) {
console.log("LATEST FROM : Value for A is " + data[1] + " ; Value for B is " + data[0]);
});
// UPDATE TO A
setTimeout(function(){
console.log("UPDATING A");
A.next(2);
},1000);
!)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.min.js"></script>
float:left
答案 1 :(得分:0)
好吧,所以我测试了你的代码。调整改变一些事情。您可以在此处查看代码:https://jsbin.com/zonedirogi/edit?html,js,console,output。主要的变化实际上是B而不是B中的最新变化,而是用B中的最新变为A.然后它按预期工作。
仅供参考,您不需要使用asObservable()
将主题转换为可观察对象。
var a = new Rx.BehaviorSubject(1);
var b = new Rx.BehaviorSubject(10);
a.subscribe(x => {
b.next(x * 10);
});
a.withLatestFrom(b).subscribe(x => {
console.log(x)
})
// UPDATE TO A
setTimeout(function(){
console.log("UPDATING A");
a.next(2);
}, 1000);