RxJS combineLatest operator怪异行为
我有一个关于RxJS combineLatest操作符的查询。我已经修改了在RxJS combineLatest operator怪异行为
https://www.learnrxjs.io/operators/combination/combinelatest.html
给出的示例如下:
//timerOne emits first value at 1s, then once every 4s
const timerOne = Rx.Observable.timer(1000, 4000);
//timerTwo emits first value at 2s, then once every 4s
const timerTwo = Rx.Observable.timer(2000, 4000)
//timerThree emits first value at 3s, then once every 4s
const timerThree = Rx.Observable.of(false);
//when one timer emits, emit the latest values from each timer as an array
const combined = Rx.Observable
.combineLatest(
timerOne,
timerTwo,
timerThree
);
const subscribe = combined.subscribe(latestValues => {
//grab latest emitted values for timers one, two, and three
const [timerValOne, timerValTwo, timerValThree] = latestValues;
if(latestValues[0] === 3) {
this.timerThree = Rx.Observable.of(true);
}
console.log(
`Timer One Latest: ${timerValOne},
Timer Two Latest: ${timerValTwo},
Timer Three Latest: ${timerValThree}`
);
});
我希望timerThree的值更改为真正位总是保持在打印假如图输出片段:
"Timer One Latest: 3,
Timer Two Latest: 2,
Timer Three Latest: false"
"Timer One Latest: 3,
Timer Two Latest: 3,
Timer Three Latest: false"
"Timer One Latest: 4,
Timer Two Latest: 3,
Timer Three Latest: false"
任何想法为什么t他正在发生?有没有什么办法解决这一问题?谢谢
这里需要注意的重要一点是timerThree
本身不是可观察的,而是对可观察对象的引用。当您使用combineLatest
时,它将组合该对象,而不是引用它的变量。因此,当您将timerThree
分配给新的可观察对象时,它现在指向一个新对象,但combined
仍在使用旧对象。
如果您希望能够更改timerThree
的值,请尝试改为使用Subject
。然后你可以通过timerThree.next
推送新值。
补充约翰的回答:
this.timerThree
未定义在latestValues[0] === 3
的时刻,因为当一个lambda函数的this
指“最近的外部范围内。
如果您要在浏览器中运行此项,this
将为window
对象,因此您只是将属性添加到窗口对象。
而且timerThree
被定义为const
的含义,如果你试图在同一对象上的重新分配它会抛出一个错误(但如上所述你分配给不同的对象。
与小提琴演奏围绕我那你想要做什么,尽管这需要努力消除重复代码的东西:
//timerOne emits first value at 1s, then once every 4s
const timerOne = Rx.Observable.timer(1000, 4000);
//timerTwo emits first value at 2s, then once every 4s
const timerTwo = Rx.Observable.timer(2000, 4000)
//timerThree emits first value at 3s, then once every 4s
let timerThree = Rx.Observable.timer(3000, 4000)
//when one timer emits, emit the latest values from each timer as an array
let combined = Rx.Observable
.combineLatest(
timerOne,
timerTwo,
timerThree
);
const subscribe = combined.subscribe(latestValues => {
//grab latest emitted values for timers one, two, and three
const [timerValOne, timerValTwo, timerValThree] = latestValues;
if(latestValues[0] === 3) {
console.log("this ===>", this);
console.log("this.timerThree ===> ", this.timerThree);
subscribe.unsubscribe();
combined = Rx.Observable.combineLatest(timerOne, timerTwo, Rx.Observable.of(true));
combined.subscribe(lvs => {
const [tv1, tv2, tv3] = lvs
console.log(
`Timer One Latest: ${tv1},
Timer Two Latest: ${tv2},
Timer Three Latest: ${tv3}`
);
})
}
console.log(
`Timer One Latest: ${timerValOne},
Timer Two Latest: ${timerValTwo},
Timer Three Latest: ${timerValThree}`
);
});
通知的unsubscribe()
呼吁防止先前合并计时器再次执行,以combineLatest
新的呼叫和新Observable
打印true
。
我也必须将timerThree
从const
更改为let
才能重新分配它。