你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 響應式編程:ReactiveCocoa vs RxSwift

響應式編程:ReactiveCocoa vs RxSwift

編輯:IOS開發基礎

QQ截圖20160122170218.png

本文為投稿文章,作者:沒故事的卓同學

內容來自stack overflow的一個回答:ReactiveCocoa vs RxSwift - pros and cons?

要直接比較這兩個有點難。Rx 是Reactive Extensions的一部分,其他語言像C#, Java 和 JS 也有。Reactive Cocoa 受 Functional Reactive Programming(FRP) 啟發,但是在最近一段時間裡,他們提到也受到Reactive Extensions的啟發。最終結果就是一個從Rx借鑒了一些東西,但是有著源自FRP名聲的一個框架。 

第一點要說明的事是無論是RAC還是Rx都不是真正意義上的Functional Reactive Programming。按照 What is (functional) reactive programming 裡的回答對於FRP概念的定義。有了這個認識,我們就可以從兩個框架如何處理subscribing/observing時的副作用(side effect)和一些其他的組件上兩個方面來比較。

我們來看看社區(community)和技術實現(extra-tech)。

RAC是一個已經有著3年歷史的項目,從Objective-C時期開始,後來從3.0開始支持了swift(可以通過bridge在OC下使用),接著就完全停止了在Objective-C上的維護。RxSwift項目的時間短一些只有幾個月(作者寫的時間是15年),但是社區似乎充滿了動力。關於RxSwift有一件重要的事是項目是按照 ReactiveX這個組織的規定下開發的,並且所有其他語言的Rx項目也是一樣。如果學會了如何使用RxSwift,再去學習Rx.Net, RxJava 或者 RxJS就是小菜一碟,只是語言語法上的差異。這真的就是learn once, apply everywhere.

再來看看技術實現。

Producing/Observing Entities

RAC 3.0主要有兩個實體,signal 和  SignalProducer。第一個發布事件無論是否有綁定訂閱者,後者要有一個信號或者事件產生才會觸發。這兩個區別是為了區分冷信號和熱信號,也使很多開發者困惑。這就是他們處理副作用的一大區別。

在RxSwift,signal 和  SignalProducer變成了 Observable,聽起來有點困惑,但是這兩個實體在Rx的世界裡是同一個東西。在RxSwift裡創建Observables不需要考慮是冷信號還是熱信號,一旦你理解了他們的工作原理就很容易掌握。再次說明 冷/熱(cold/hot/warm)信號就是當你subscribing/observing 產生的副作用。

對於訂閱的概念兩者基本是一樣的。在RAC裡有一點小的區別,RAC可以中斷一個事件當信號被  disposed,即使在事件發送完成信號之前。總結一下兩者都有的以下事件:

  • Next
    處理新收到的值

  • Error
    處理一個錯誤,結束整個流,對所有的觀察者取消訂閱

  • Complete
    標記整個流已經完成,取消所有觀察者的訂閱
    另外RAC會在收到一個disposed Signal後中斷,即使沒有收到complete或者error。

Manually Writing

在RAC中,Signal/SignalProducer都是只讀的實體,他們不能從外部被改變,RxSwift中的Observable也是如此。如果要把Signal/SignalProducer改變成可以手動改寫的實體,你只能通過調用pipe()函數返回一個可以改動的對象。在Rx中,這是一個不同的類型叫做Subject。
如果讀/寫這樣的概念聽起來不太明白,可以類比為未來/承諾(Future
/Promise)。未來只是一個只讀的占位符(A Future is a read-only placeholder),就像Signal/SignalProducer和Observable。另外一方面,對於未來的承諾確可以手動自由的實現,就像pipe()和Subject。

Schedulers

這個部分兩個框架都很類似,同樣的概念。但是RAC是連續的,串行,Rx可以支持並發。

Composition

合成(Composition)是響應式編程的主要特點。合成成流都是兩個框架的核心,在Rx中也稱作sequences。
在Rx中所有observable的實體的類型都是ObservableType,所以我們可以輕松的用同一個操作符將Subject和Observable的實例組合(compose)起來。
在RAC中,Signal和SignalProducer是兩種不同的對象。我們必須把SignalProducer轉換成Signal後才能compose由Signal實例產生的信號。這兩個對象擁有各自的操作符。所以當你需要混合使用它們時,你必須考慮到某種操作符是否是兩者通用,這個時候你也不必關心冷/熱的處理了。

關於這個部分, Colin Eberhardt 很好的總結了:
現在signal的API主要關注在處理‘next’上,讓你可以改變值,skip、delay、combine並且在不同的線程裡觀察值。signal producer的API主要處理信號的生命周期事件(completed, error),和一些這樣的操作:then, flatMap, takeUntil 和catch。

其他

在RAC中還有Action和 Property的概念。前者是一種處理副作用的類型,主要和用戶交互相關。後者用於觀察當執行了一個任務後值改變了的情況。在Rx中Action也會轉變(translate)成一個 Observable類型。這在RxCocoa中有很好的體現,一個集成了Rx基本元素後用於iOS和Mac平台。RAC中的 Property可以對應於Rx中的 Variable或者 BehaviourSubject。
明白 Property/ Variable是我們連接必然世界和聲明本質的響應式編程的的橋梁(bridge the imperative world to the declarative nature of Reactive Programming),所以當我們處理一些第三方庫或者iOS/Mac中的核心功能(functionalities)時, Property/ Variable有時是基礎。

結論

RAC和Rx可以說是兩種完全不同的物種,前者在Cocoa裡有著長的歷史和大量的參與者,後者很年輕,但是依靠著已經在其他語言裡像java、js或者C#被驗證過的有效理念。關於選誰比較好還是要考慮到自己的情況。RAC認為把觀察的對象區分為熱/冷是非常有必要的,並且這也是他們框架的一個核心特點。Rx則認為把這個統一為一種對象更好。再次說明,這影響的只是怎麼處理訂閱後的副作用。
RAC 3.0 在為了區分觀察時的熱/冷狀態還引入了意料之外的復雜度,比如中斷的概念,區分兩種對象間不同的操作,引入一些必要行為(imperative behaviour)比如start是開始產生信號。對於一些人來說,這些東西很好甚至是一個殺手級功能,對於另外一些人而言會覺得這個並沒有必要甚至有些危險。另外需要記住的一點是RAC一直努力和Cocoa的慣例盡量保持一致,如果你是一個資深的Cocoa開發者,你在使用RAC應該會覺得比Rx更順手。
Rx中所有的對象都是observables。好的一件事是,是Reactive Extensions中的一員。從RxJS, RxJava 或者 Rx.Net中遷移過來是一件非常簡單的事,所有概念都是一樣的。這也讓解決問題時會很有趣,因為你現在面臨的問題,可能在RxJava中已經有人寫過解決方案,你可以直接拿過來按照當前平台實現就可以。
這兩個應該選哪一個關鍵看使用習慣,從一個客觀的角度來說無法分辨出誰更好。最好的方式是打開Xcode,都試著使用這兩個框架,看看那個用起來比較順手。他們都是相同編程理念的實現,嘗試達到同一個目的:使開發軟件變得簡單(simplifying software development)。

相關鏈接:
函數式反應型編程(FRP) —— 實時互動應用開發的新思路
C語言裡的side effect是什麼意思?

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved