RxJava開發精要

1 - 從.NET到RxJava

RX - 從.NET到RxJava

響應式編程是一種基于異步數據流概念的編程模式。數據流就像一條河:它可以被觀測,被過濾,被操作,或者為新的消費者與另外一條流合并為一條新的流。

響應式編程的一個關鍵概念是事件。事件可以被等待,可以觸發過程,也可以觸發其它事件。事件是唯一的以合適的方式將我們的現實世界映射到我們的軟件中:如果屋里太熱了我們就打開一扇窗戶。同樣的,當我們更改電子表(變化的傳播)中的一些數值時,我們需要更新整個表格或者我們的機器人碰到墻時會轉彎(響應事件)。

今天,響應式編程最通用的一個場景是UI:我們的移動App必須做出對網絡調用、用戶觸摸輸入和系統彈框的響應。在這個世界上,軟件之所以是事件驅動并響應的是因為現實生活也是如此。

微軟響應式擴展

函數響應式編程是一個來自90年代后期受微軟的一名計算機科學家Erik Meijer啟發的思想,用來設計和開發微軟的Rx庫。

Rx 是微軟.NET的一個響應式擴展。Rx借助可觀測的序列提供一種簡單的方式來創建異步的,基于事件驅動的程序。開發者可以使用Observables模擬異步數據流,使用LINQ語法查詢Observables,并且很容易管理調度器的并發。

Rx讓眾所周知的概念變得易于實現和消費,例如push方法。在響應式的世界里,我們不能假裝作用戶不關注或者是不抱怨它而一味的等待函數的返回結果,網絡調用,或者數據庫查詢的返回結果。我們時刻都在等待某些東西,這就讓我們失去了并行處理其他事情的機會,提供更好的用戶體驗,讓我們的軟件免受順序鏈的影響,而阻塞編程。

下表列出的與.NET 枚舉相關的.NET Observable

.NET Observable 一個返回值 多個返回值
Pull/Synchronous/Interactive T IEnumerable<T>
Push/Asynchronous/Reactive Task<T> IObservable<T>

push方法把這個問題逆轉了:取而代之的是不再等待結果,開發者只是簡單的請求結果,而當它返回時得到一個通知即可。開發者對即將發生的事件提供一個清晰的響應鏈。對于每一個事件,開發者都作出相應的響應;例如,用戶被要求登錄的時候,提交一個攜帶他的用戶名和密碼的表單。應用程序執行登錄的網絡請求,接下來將要發生的情況有:

  • 顯示一個成功的信息,并保存用戶的個人信息。
  • 顯示一個錯誤的信息

正如你用push方法所看到的,開發者不需要等待結果。而是在結果返回時通知他。在這期間,他可以做他想做的任何事情:

  • 顯示一個進度對話框
  • 為下次登錄保存用戶名和密碼
  • 預加載一些他認為登錄成功后需要耗時處理的事情

來到Java世界 - Netflix RxJava

Netflix在2012年開始意識到他們的架構要滿足他們龐大的用戶群體已經變得步履維艱。因此他們決定重新設計架構來減少REST調用的次數。取代幾十次的REST調用,而是讓客戶端自己處理需要的數據,他們決定基于客戶端需求創建一個專門優化過的REST調用。

為了實現這一目標,他們決定嘗試響應式,開始將.NET Rx遷移到JVM上面。他們不想只基于Java語言;而是整個JVM,從而有可能為市場上的每一種基于JVM的語言:如Java、Closure、Groovy、Scala等等提供一種新的工具。

2013年二月份,Ben Christensen 和 Jafar Husain發在Netflix技術博客的一篇文章第一次向世界展示了RxJava。

主要特點有:

  • 易于并發從而更好的利用服務器的能力。
  • 易于有條件的異步執行。
  • 一種更好的方式來避免回調地獄。
  • 一種響應式方法。

正如.NET,RxJava Observable 是push 迭代的等價體,即pull。pull方法是阻塞并等待的方法:消費者從源頭pull值,并阻塞線程直到生產者提供新的值。

push方法作用于訂閱和響應:消費者訂閱新值的發射,當它們可用時生產者push這些新值并通知消費者。在這一點上,消費者消費了它們。push方法很明顯更靈活,因為從邏輯和實踐的觀點來看,開發者只需忽略他需要的數據是來自同步還是異步;他的代碼將仍然起作用。

RxJava的與眾不同之處

從純Java的觀點看,RxJava Observable類源自于經典的Gang Of Four的觀察者模式。

它添加了三個缺少的功能:

  • 生產者在沒有更多數據可用時能夠發出信號通知:onCompleted()事件。
  • 生產者在發生錯誤時能夠發出信號通知:onError()事件。
  • RxJava Observables 能夠組合而不是嵌套,從而避免開發者陷入回調地獄。

Observables和Iterables共用一個相似的API:我們在Iterable可以執行的許多操作也都同樣可以在Observables上執行。當然,由于Observables流的本質,沒有如Iterable.remove()這樣相應的方法。

Pattern 一個返回值 多個返回值
Synchronous T getData() Iterable<T>
Asynchronous Future<T> getData() Observable<T> getData()

從語義的角度來看,RxJava就是.NET Rx。從語法的角度來看,Netflix考慮到了對應每個Rx方法,保留了Java代碼規范和基本的模式。

總結

本章中,我們初步探索了響應式的世界。從微軟的.NET到Netflix的RxJava,我們了解了Rx是如何誕生的,我們也了解到傳統的方法與響應式方法相比之間的相似和不同。

下一章,我們將學習到Observables是什么,以及如何創建它并把響應式編程應用到我們的日常編碼中去。

25选5玩法中奖