[英]RxJS combineLatest operator weird behaviour
我有一個關於RxJS combineLatest運算符的查詢。 我修改了給出的例子
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的值更改為true位,它始終保持打印錯誤 ,如輸出片段所示:
"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"
知道為什么會這樣嗎? 有沒有什么辦法解決這一問題? 謝謝
需要注意的重要一點是timerThree
本身不是一個可觀察的,而是一個可觀察對象的引用。 當您使用combineLatest
,它正在組合該對象,而不是引用它的變量。 因此,當您將timerThree
分配給新的observable時,它現在指向一個新對象,但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
才能夠重新分配它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.