簡體   English   中英

RxJS結合了最簡單的運算符奇怪的行為

[英]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.timerThreelatestValues[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

我也不得不改變timerThreeconstlet才能夠重新分配它。

小提琴

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM