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的童鞋完全搞不懂 ^_^ (神马心态) ]

尤雨溪 前端开发、JavaScript、前端工程师 话题的优秀回答者 100 人赞同了该回答 先说观点,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 性能好 + 单向数据流应对复杂度,对其本质却不知其所以然...) 编辑于 2016-11-07 100 11 条评论 分享 收藏收起 鲁小夫 前端开发、JavaScript 话题的优秀回答者 还好吧,我觉得 event stream 比 imperative style 可读多了 发布于 2016-02-07 0 添加评论 分享 收藏 米嘉 怪兽工程师 15 人赞同了该回答 RxJS/Cycle.js解决的是数据流的问题,为什么有数据流的问题,是因为更倾向于或者受限于使用单向数据绑定,核心其实解决的是State管理的问题。偏向于Redux或者Flux架构会有全局State的困扰,而最近Redux作者也在新的文章中写到“Local State is Fine”, https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367#.m8dop3xqq 我们厂(小厂)在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 发布于 2016-09-28 15 添加评论 分享 收藏 Wang Namelos 宇宙级React开发 2 人赞同了该回答 我只能说Cycle是大炮,但是打蚊子一点不麻烦。就说打包比React小,本身Observable就是stage-1提案,有一天标准发布Cycle体积几乎就只有Virtual DOM了。 部分引入Rx只会获得部分收益,总要从Observable这个monad容器出来进去,导致编码本身大量冗余,丢掉大部分FP的好处。 用用Cycle你就能发现比React大量的手动绑定简洁多了,这样重构也方便。Cycle效率真心远超React Redux,这取决于React onClick绑定,导致要做到类似Reactive Programming的效果(Flux / Redux 对React来说是标配),需要做大量重复工作,Flux只是模式,导致不能真的抽象成库。这是React为数不多的硬伤。 缺点就是Rx4测试困难,如果你们不要求覆盖率,调试Rx其实并不是很麻烦的事情。 发布于 2016-03-14 2 添加评论 分享 收藏 沈嵘 产品总监 22 人赞同了该回答 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 是一种“对”的开发方式。 看 Doc 和 Tutorial 真是很精彩,作者是反应式编程的铁杆粉丝,自己也造了诸如 xstream 这样的轮子,HCI 的理念很不错,但是能用好它的开发者应该不多,强制全盘在 Reactive 的闭环内进行编程,没有非常优秀的 FRP 基础很难在状态规模变得十分庞大的情况下理清各个事件流之间的关系。它可以加深你对 FRP 的理解,但我不认为它适用于去做真正的项目,你的团队就没有这个能力去全盘使用它。

尤雨溪

前端开发JavaScript前端工程师 话题的优秀回答者

先说观点,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 性能好 + 单向数据流应对复杂度,对其本质却不知其所以然...)

编辑于 2016-11-07

分享

鲁小夫

前端开发JavaScript 话题的优秀回答者

还好吧,我觉得 event stream 比 imperative style 可读多了

发布于 2016-02-07

分享

米嘉

怪兽工程师

RxJS/Cycle.js解决的是数据流的问题,为什么有数据流的问题,是因为更倾向于或者受限于使用单向数据绑定,核心其实解决的是State管理的问题。偏向于Redux或者Flux架构会有全局State的困扰,而最近Redux作者也在新的文章中写到“Local State is Fine”, https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367#.m8dop3xqq

我们厂(小厂)在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

发布于 2016-09-28

分享

Wang Namelos

宇宙级React开发

我只能说Cycle是大炮,但是打蚊子一点不麻烦。就说打包比React小,本身Observable就是stage-1提案,有一天标准发布Cycle体积几乎就只有Virtual DOM了。

部分引入Rx只会获得部分收益,总要从Observable这个monad容器出来进去,导致编码本身大量冗余,丢掉大部分FP的好处。

用用Cycle你就能发现比React大量的手动绑定简洁多了,这样重构也方便。Cycle效率真心远超React Redux,这取决于React onClick绑定,导致要做到类似Reactive Programming的效果(Flux / Redux 对React来说是标配),需要做大量重复工作,Flux只是模式,导致不能真的抽象成库。这是React为数不多的硬伤。

缺点就是Rx4测试困难,如果你们不要求覆盖率,调试Rx其实并不是很麻烦的事情。

发布于 2016-03-14

分享

沈嵘

产品总监

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 是一种“对”的开发方式。

发布于 2016-02-08

分享

Cyandev

大二学生,资深果粉,编程初学者

看 Doc 和 Tutorial 真是很精彩,作者是反应式编程的铁杆粉丝,自己也造了诸如 xstream 这样的轮子,HCI 的理念很不错,但是能用好它的开发者应该不多,强制全盘在 Reactive 的闭环内进行编程,没有非常优秀的 FRP 基础很难在状态规模变得十分庞大的情况下理清各个事件流之间的关系。它可以加深你对 FRP 的理解,但我不认为它适用于去做真正的项目,你的团队就没有这个能力去全盘使用它。

发布于 2016-11-12

分享

凌柏超

妹子 滚床单吗 滚

可惜很多人只会跟风大牛 reactive的确可以使代码清晰些 希望大家多看看

发布于 2016-02-07

分享