[英]How does RxJava Observable “Iteration” work?
我開始玩RxJava和ReactFX,我對它非常着迷。 但是當我在試驗時,我有幾十個問題而且我一直在研究答案。
我正在觀察的一件事(沒有雙關語意)當然是懶惰的執行。 使用下面的探索性代碼,我注意到在merge.subscribe(pet -> System.out.println(pet))
之前沒有執行任何操作。 但令我着迷的是,當我訂閱第二個訂閱者merge.subscribe(pet -> System.out.println("Feed " + pet))
,它再次觸發了“迭代”。
我想要了解的是迭代的行為。 它似乎不像只能使用一次的Java 8 stream
。 它是否逐字逐句地遍歷每個String
並將其作為該時刻的值發布? 任何以前被解雇的用戶跟隨任何新訂閱者接收這些項目是否像新的一樣?
public class RxTest {
public static void main(String[] args) {
Observable<String> dogs = Observable.from(ImmutableList.of("Dasher", "Rex"))
.filter(dog -> dog.matches("D.*"));
Observable<String> cats = Observable.from(ImmutableList.of("Tabby", "Grumpy Cat", "Meowmers", "Peanut"));
Observable<String> ferrets = Observable.from(CompletableFuture.supplyAsync(() -> "Harvey"));
Observable<String> merge = dogs.mergeWith(cats).mergeWith(ferrets);
merge.subscribe(pet -> System.out.println(pet));
merge.subscribe(pet -> System.out.println("Feed " + pet));
}
}
Observable<T>
表示monad,一個鏈式操作,而不是操作本身的執行。 它是描述性語言,而不是您習慣的命令。 要執行操作,請使用.subscribe()
。 每次訂閱時,都會從頭開始創建新的執行流。 不要將流與線程混淆,因為訂閱是同步執行的,除非您使用.subscribeOn()
或.observeOn()
指定線程更改 。 您將新元素鏈接到任何現有操作/ monad / Observable以添加新行為 ,例如更改線程,過濾,累積,轉換等。如果您的observable是一項昂貴的操作,您不想在每個訂閱上重復,您可以使用.cache()
防止重新創建。
要將任何異步/同步Observable<T>
操作轉換為同步內聯操作,請使用.toBlocking()
將其類型更改為BlockingObservable<T>
。 而不是.subscribe()
它包含用.forEach()
對每個結果執行操作的新方法,或強制使用.forEach()
.first()
Observable是一個很好的工具,因為它們大多數是*確定性的(相同的輸入總是產生相同的輸出,除非你做錯了),可重用(你可以將它們作為命令/策略模式的一部分發送)並且大多數情況下忽略同意,因為他們不應該依賴共享狀態(也就是說做錯了)。 如果你試圖將一個基於可觀察的庫帶入命令式語言,或者只是在一個Observable上執行一個你有100%信心並且管理良好的操作,那么BlockingObservables是很好的。
圍繞這些原則構建應用程序是一種范式的改變,我無法真正涵蓋這個答案。
*像
Subject
和Observable.create()
這樣的漏洞需要與命令式框架集成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.