簡體   English   中英

RxJS - Fire按順序訂閱

[英]RxJS - Fire subscribes in order

我試圖找出RxJS模式來聲明我的“訂閱”,以便它們按順序執行。

這是我所處的情況:

var flag = false;

// Stream that non-deterministically emits `true` when flag is true
var random$ = Rx.Observable.interval(1000)
  .map(() => setFlagToRandomTrueOrFalse())
  .filter(x => x)
  .first();

// How can I declare my "subscribes" so that the console.logs happen in order?
var sub1 = random$.subscribe(() => console.log(1), console.log, resetFlagToFalse);
var sub2 = random$.subscribe(() => console.log(2), console.log, resetFlagToFalse);

function setFlagToRandomTrueOrFalse() {
  flag = flag || !!Math.floor(Math.random() * 2);
  return flag;
}

function resetFlagToFalse() { flag = false; }

由於.subscribe的異步性質,這當前以隨機順序打印12

另外,這些“訂閱”的正確名稱是什么? 總RxJS noob在這里。

eeerr我不確定你觀察的順序是因為subscribe的異步性質。

首先,正如目前所寫, random$是一個冷源,即尚未訂閱的生產者。 每次訂閱時,該制作人都會開始制作。 這意味着在這里,你將啟動生產者兩次,所以你將為每個生成兩個不同的隨機值,所以日志將在不同的時間顯示,因為你沒有訂閱相同的值序列,即使它看起來非常喜歡。

關於冷流和熱流之間區別的更清晰的描述是熱和冷的可觀測量:是否存在“熱”和“冷”運算符? 花費盡可能多的時間來理解這一點,因為在您開始使用Rxjs做任何事情之前,這非常重要。

如果要訂閱相同的值序列,即如果您希望生產者將其值多播到所有訂戶(熱行為),而不是為每個訂戶重新啟動(冷行為),則需要使用multicast的變體運營商,如上述鏈接中所述。 這意味着在你的情況下

var random$ = Rx.Observable.interval(1000)
    .map(() => setFlagToRandomTrueOrFalse())
    .filter(x => x)
    .share();

回到你關於數據傳播順序的問題,它確實主要是確定性的,並不意味着總是很簡單。 在您的簡單情況下,第一個訂閱確實將首先執行。 這是因為在引擎蓋下,類似multicast的運營商正在使用主題,它按訂閱順序立即(熱源)將它們收到的值發送給所有訂戶。 有關主題的信息,請查看不同RxJS主題的​​語義是什么?

最后,如果你編寫純函數,它可以幫助推理你的溪流。 擁有諸如flag類的閉包變量會讓事情變得非常復雜。

我建議你先看看這里,然后再深入研究Rxjs: 你一直缺少的Reactive Programming簡介

您可以使用publish() and connect()按順序執行操作

 var flag = false; // Stream that non-deterministically emits `true` when flag is true var random$ = Rx.Observable.interval(1000) .map(() => setFlagToRandomTrueOrFalse()) .filter(x => x) .first().publish(); // How can I declare my "subscribes" so that the console.logs happen in order? var sub1 = random$.subscribe(() => console.log(1), console.log, resetFlagToFalse); var sub2 = random$.subscribe(() => console.log(2), console.log, resetFlagToFalse); random$.connect(); function setFlagToRandomTrueOrFalse() { flag = flag || !!Math.floor(Math.random() * 2); return flag; } function resetFlagToFalse() { flag = false; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script> 

暫無
暫無

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

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