內容來自stack overflow的一個回答:ReactiveCocoa vs RxSwift - pros and cons?
要直接比較這兩個有點難。Rx 是 Reactive Extensions 的一部分眷蜓,其他語言像C#, Java 和 JS 也有葡盗。Reactive Cocoa 受 Functional Reactive Programming(FRP) 啟發(fā),但是在最近一段時間里方援,他們提到也受到Reactive Extensions的啟發(fā)酝陈。最終結果就是一個從Rx借鑒了一些東西营罢,但是有著源自FRP名聲的一個框架。
第一點要說明的事是無論是RAC還是Rx都不是真正意義上的Functional Reactive Programming仲智。按照 What is (functional) reactive programming 里的回答對于FRP概念的定義买乃。有了這個認識,我們就可以從兩個框架如何處理subscribing/observing時的副作用(side effect)和一些其他的組件上兩個方面來比較钓辆。
我們來看看社區(qū)(community)和技術實現(xiàn)(extra-tech)剪验。
RAC是一個已經(jīng)有著3年歷史的項目,從Objective-C時期開始前联,后來從3.0開始支持了swift(可以通過bridge在OC下使用)功戚,接著就完全停止了在Objective-C上的維護。RxSwift項目的時間短一些只有幾個月(作者寫的時間是15年)似嗤,但是社區(qū)似乎充滿了動力啸臀。關于RxSwift有一件重要的事是項目是按照 ReactiveX這個組織的規(guī)定下開發(fā)的,并且所有其他語言的Rx項目也是一樣烁落。如果學會了如何使用RxSwift乘粒,再去學習Rx.Net, RxJava 或者 RxJS就是小菜一碟,只是語言語法上的差異伤塌。這真的就是learn once, apply everywhere.
再來看看技術實現(xiàn)谓厘。
Producing/Observing Entities
RAC 3.0主要有兩個實體,<code>signal</code> 和 <code> SignalProducer </code>寸谜。第一個發(fā)布事件無論是否有綁定訂閱者竟稳,后者要有一個信號或者事件產(chǎn)生才會觸發(fā)。這兩個區(qū)別是為了區(qū)分冷信號和熱信號熊痴,也使很多開發(fā)者困惑他爸。這就是他們處理副作用的一大區(qū)別。
在RxSwift果善,<code>signal</code> 和 <code> SignalProducer </code>變成了<code> Observable </code>诊笤,聽起來有點困惑,但是這兩個實體在Rx的世界里是同一個東西巾陕。在RxSwift里創(chuàng)建Observables不需要考慮是冷信號還是熱信號讨跟,一旦你理解了他們的工作原理就很容易掌握。再次說明 冷/熱(cold/hot/warm)信號就是當你subscribing/observing 產(chǎn)生的副作用鄙煤。
對于訂閱的概念兩者基本是一樣的晾匠。在RAC里有一點小的區(qū)別,RAC可以中斷一個事件當信號被 <code> disposed </code>梯刚,即使在事件發(fā)送完成信號之前凉馆。總結一下兩者都有的以下事件:
- <code> Next </code>
處理新收到的值 - <code> Error </code>
處理一個錯誤,結束整個流澜共,對所有的觀察者取消訂閱 - <code> Complete </code>
標記整個流已經(jīng)完成向叉,取消所有觀察者的訂閱
另外RAC會在收到一個disposed Signal后中斷,即使沒有收到complete或者error嗦董。
Manually Writing
在RAC中母谎,Signal/SignalProducer都是只讀的實體,他們不能從外部被改變京革,RxSwift中的Observable也是如此销睁。如果要把Signal/SignalProducer改變成可以手動改寫的實體,你只能通過調用<code>pipe()</code>函數(shù)返回一個可以改動的對象存崖。在Rx中冻记,這是一個不同的類型叫做<code>Subject</code>。
如果讀/寫這樣的概念聽起來不太明白来惧,可以類比為未來/承諾(Future
/Promise)冗栗。未來只是一個只讀的占位符(A Future is a read-only placeholder),就像Signal/SignalProducer和Observable供搀。另外一方面隅居,對于未來的承諾確可以手動自由的實現(xiàn),就像pipe()和Subject葛虐。
Schedulers
這個部分兩個框架都很類似胎源,同樣的概念。但是RAC是連續(xù)的屿脐,串行涕蚤,Rx可以支持并發(fā)。
Composition
合成(Composition)是響應式編程的主要特點的诵。合成成流都是兩個框架的核心万栅,在Rx中也稱作sequences。
在Rx中所有observable的實體的類型都是<code>ObservableType</code>西疤,所以我們可以輕松的用同一個操作符將Subject和Observable的實例組合(compose)起來烦粒。
在RAC中,Signal和SignalProducer是兩種不同的對象代赁。我們必須把SignalProducer轉換成Signal后才能compose由Signal實例產(chǎn)生的信號扰她。這兩個對象擁有各自的操作符。所以當你需要混合使用它們時芭碍,你必須考慮到某種操作符是否是兩者通用徒役,這個時候你也不必關心冷/熱的處理了。
關于這個部分豁跑, Colin Eberhardt 很好的總結了:
現(xiàn)在signal的API主要關注在處理‘next’上廉涕,讓你可以改變值泻云,skip, delay, combine并且在不同的線程里觀察值艇拍。signal producer的API主要處理信號的生命周期事件(completed, error)狐蜕,和一些這樣的操作:then, flatMap, takeUntil 和catch。
其他
在RAC中還有<code>Action</code>和<code> Property </code>的概念卸夕。前者是一種處理副作用的類型层释,主要和用戶交互相關。后者用于觀察當執(zhí)行了一個任務后值改變了的情況快集。在Rx中<code>Action</code>也會轉變(translate)成一個<code> Observable </code>類型贡羔。這在RxCocoa中有很好的體現(xiàn),一個集成了Rx基本元素后用于iOS和Mac平臺个初。RAC中的<code> Property </code>可以對應于Rx中的<code> Variable </code>或者<code> BehaviourSubject </code>乖寒。
明白<code> Property </code>/<code> Variable </code>是我們連接必然世界和聲明本質的響應式編程的的橋梁(bridge the imperative world to the declarative nature of Reactive Programming),所以當我們處理一些第三方庫或者iOS/Mac中的核心功能(functionalities)時院溺,<code> Property </code>/<code> Variable </code>有時是基礎楣嘁。
結論
RAC和Rx可以說是兩種完全不同的物種,前者在Cocoa里有著長的歷史和大量的參與者珍逸,后者很年輕逐虚,但是依靠著已經(jīng)在其他語言里像java、js或者C#被驗證過的有效理念谆膳。關于選誰比較好還是要考慮到自己的情況叭爱。RAC認為把觀察的對象區(qū)分為熱/冷是非常有必要的,并且這也是他們框架的一個核心特點漱病。Rx則認為把這個統(tǒng)一為一種對象更好买雾。再次說明,這影響的只是怎么處理訂閱后的副作用杨帽。
RAC 3.0 在為了區(qū)分觀察時的熱/冷狀態(tài)還引入了意料之外的復雜度凝果,比如中斷的概念,區(qū)分兩種對象間不同的操作睦尽,引入一些必要行為(imperative behaviour)比如<code>start</code>是開始產(chǎn)生信號器净。對于一些人來說,這些東西很好甚至是一個殺手級功能当凡,對于另外一些人而言會覺得這個并沒有必要甚至有些危險山害。另外需要記住的一點是RAC一直努力和Cocoa的慣例盡量保持一致,如果你是一個資深的Cocoa開發(fā)者沿量,你在使用RAC應該會覺得比Rx更順手浪慌。
Rx中所有的對象都是observables。好的一件事是朴则,是Reactive Extensions中的一員权纤。從RxJS, RxJava 或者 Rx.Net中遷移過來是一件非常簡單的事,所有概念都是一樣的。這也讓解決問題時會很有趣汹想,因為你現(xiàn)在面臨的問題外邓,可能在RxJava中已經(jīng)有人寫過解決方案,你可以直接拿過來按照當前平臺實現(xiàn)就可以古掏。
這兩個應該選哪一個關鍵看使用習慣损话,從一個客觀的角度來說無法分辨出誰更好。最好的方式是打開Xcode槽唾,都試著使用這兩個框架丧枪,看看那個用起來比較順手。他們都是相同編程理念的實現(xiàn)庞萍,嘗試達到同一個目的:使開發(fā)軟件變得簡單(simplifying software development)拧烦。
歡迎關注我的微博:@沒故事的卓同學
相關鏈接:
函數(shù)式反應型編程(FRP) —— 實時互動應用開發(fā)的新思路
C語言里的side effect是什么意思?