RxJS/Cycle.js 與 React/Vue 相比更適用於什么樣的應用場景?
RxJS/Cycle.js 與 React/Vue 相比更適用於什么樣的應用場景? - 知乎 https://www.zhihu.com/question/40195289
實際項目中,React, Vue 等就很方便了。而使用 Rxjs, Cycle.js 會引入大量的函數式概念,無法輕松融入現有項目。
對於全新前端項目來說,要完全投入 Cycle.js 的懷抱也總有大炮打蚊子的感覺,畢竟前端項目充滿了各種狀態,變量,副作用。快速迭代時,為了臨時業務需要,也會容忍一些反模式的代碼出現。
那么對於前端項目來說,Rxjs,Cycle.js 更適用於何種場景呢?
這個 app 還沒復雜到需要讓我忍受
action$.startWith( 0 ).scan( ( x, y ) => x + y )
這樣代碼的程度。
[其實個人感覺這樣的代碼含蠻帶感的哎( 是我 2 young, 2 simple 么),畢竟看起來高大上,會讓那些只會jq的童鞋完全搞不懂 ^_^ (神馬心態) ]先說觀點,React/Vue 和 Cycle 一起用是不太合理的,因為 Cycle 本身定位是框架,定義了整個應用的代碼組織方式和開發范式,那就是無論是用戶事件處理還是服務端數據同步,統統用 Rx 來做,Cycle 自己也提供了偏好的 view layer(基於 virtual-dom 的 DOM driver)。總的來說 Cycle 的范式侵入性很強,屬於要么不用要用就得全盤接受 Rx for everything 的理念。我本身對於這個理念持保留態度,同時目前還沒有看到過大型 Cycle 應用的例子,那么自然對於 Cycle 到底好不好用,也是持保留態度。
另一方面,在 React/Vue 應用中部分使用 Rx 是完全沒有問題的。思路上來說就是把 React/Vue 組件的 local state 當做一個『中介』,在一個 Rx Observable 的 subscribe 回調里面更新組件狀態。通過簡單的綁定庫支持,可以完全把 component state 作為一個實現細節封裝掉,實現 Observable -> view 的聲明式綁定。參考:
- Vue + Rx: https://github.com/vuejs/vue-rx/
- React + Rx: GitHub - belfz/fully-reactive-react-example
我個人傾向於在適合 Rx 的地方用 Rx,但是不強求 Rx for everything。比較合適的例子就是比如多個服務端實時消息流,通過 Rx 進行高階處理,最后到 view 層就是很清晰的一個 Observable,但是 view 層本身處理用戶事件依然可以沿用現有的范式。
---
題外話,
的答案拿 Vue 說事,然后說不可避免會遇到『性能牆』問題,而 Virtual DOM 是 React 對『性能牆』的解決方案,我只能說這個看法基本屬於對 Virtual DOM 理解停留在宣傳層面的水平。詳見 網上都說操作真實 DOM 慢,但測試結果卻比 React 更快,為什么? - 尤雨溪的回答。而關於『復雜度牆』,則要么是對『單向數據流』的理解停留在宣傳層面,要么是對 Vue 的了解有限(不了解您可以少說兩句)。React 如果沒有 Flux,其實也是依賴 component local state。React + Redux 做的事情說到底就是把應用狀態從組件本身隔離出去統一管理,這種思路 並不是只有 React 能做到,只要有個聲明式的視圖層就行了。這也是為什么 Redux 是 view-layer agnostic,Vue,Angular 2 都有配合 Redux 使用的例子,Vue 自己也有專屬的狀態管理方案 Vuex。(這些話我其實在知乎重復過好幾遍了,只是太多人被 FB 的宣傳洗了腦,說 React 必提 virtual dom 性能好 + 單向數據流應對復雜度,對其本質卻不知其所以然...)
我們廠(小廠)在iOS(Native)、Android(ReactNative)和Web上都選擇了Data Flow驅動的設定思路,使用RxJS(RxSwift)來作為Data Flow驅動的核心組件,架構基本類似,把全局狀態和組件局部狀態分開,結構很清楚,因為Data Flow會讓你比較容易追蹤到數據變化的原因,最終導致UI變化的原因。其實只要把全局狀態和局部狀態有效管理,使用Redux也很好,不過使用RxJS是因為我們可以很輕松的把全局狀態Stream和組件局部狀態的Stream通過Rx運算子共同運算,代碼會更加清晰,同時大大減少對全局狀態的污染,有效控制數據狀態變化傳播的范圍。
Reactive programming is oriented around data flows and the propagation of change. Erik Meijer gave us Rx because he was induced by push-based systems. When you want to stay up to date about the state of the world, it is much better to push instead of to pull.
Observable Stream + FRP圍繞數據流驅動設計App架構,會大大減少UI上的復雜度,非常看好的結構方向。
而React本身定義了數據流向的要求,但是沒有定義如何解決這個問題,所以,React和RxJS解決的不是一個問題……They have not solved the problem of how to achieve explicit data-flow graphs
https://medium.com/@fkrautwald/plug-and-play-all-your-observable-streams-with-cycle-js-e543fc287872#.zcbj1db3x
部分引入Rx只會獲得部分收益,總要從Observable這個monad容器出來進去,導致編碼本身大量冗余,丟掉大部分FP的好處。
用用Cycle你就能發現比React大量的手動綁定簡潔多了,這樣重構也方便。Cycle效率真心遠超React Redux,這取決於React onClick綁定,導致要做到類似Reactive Programming的效果(Flux / Redux 對React來說是標配),需要做大量重復工作,Flux只是模式,導致不能真的抽象成庫。這是React為數不多的硬傷。
缺點就是Rx4測試困難,如果你們不要求覆蓋率,調試Rx其實並不是很麻煩的事情。
Vue 的年齡輕,但是 Vue 卻是最傳統的基於 observer 的MVC,但是做到了盡量簡單。但是不可避免的,當你的 Web App 越來越復雜,自然也會撞到兩堵牆,"性能牆"和"復雜度牆"(否則也就不會有React, Cycle.js..., Angular早就一統江湖了)。
React 針對"性能牆"的方案就是 VirtualDOM,對於"復雜度牆"的方案就是單向數據流,希望用一些"函數式"的概念來規避過於復雜的狀態維護(對於稍微復雜一些的應用,這是一定會出現的問題)。但是由於 React 自身不是"函數式"的,又有大量的工程妥協,因此真的是充滿了 boilerplate。
Cycle.js 其實是 FRP 在 Web App 領域的一種"模式"(Source/Driver, MVI),是天生用來對付"復雜度牆"的。而且,得益於 React 的思路, Cycle.js 也老大不客氣地把 VirtualDOM 拿來緩解"性能牆"問題。
但是,由於 Cycle.js 尚沒有被大量的開發者使用,缺少工程驗證,尤其是性能評估方面;而且也沒有大廠持續地投資,所以還是在探索階段。不過以我個人體驗來看,Cycle.js 是一種“對”的開發方式。





