Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

精读《单页应用的数据流方案探索》 #18

Open
ascoders opened this issue May 10, 2017 · 0 comments
Open

精读《单页应用的数据流方案探索》 #18

ascoders opened this issue May 10, 2017 · 0 comments

Comments

@ascoders
Copy link
Owner

1 引言

前几期精读了前端模块化、语法相关的文章,这次讨论另一个举足轻重的话题:数据流。
数据流在前端的地位与工程化、可视化、组件化是一样重要的,没有好的数据流框架与思想的指导,业务代码长期肯定倾向于不可维护的状态,当项目不断增加功能后,管理数据变得更加重要。

早期前端是没有数据流概念的,因为前端非常薄,每个页面只要展示请求数据,不需要数据流管理。

随着前端越来越复杂,框架越来越内聚,数据流方案由分到合,由合又到了分,如今数据流逐渐从框架中解绑,形成了一套通用体系,供各个框架使用。

虽然数据流框架很多,但基本上可以分为 双向数据流党单向数据流党响应式数据流党,分别以 MobxReduxRxjs 为代表呈现三国鼎立之状,顺带一提,对 css 而言也有 css in js 和纯 css党 势均力敌,前端真是不让人省心啊。这次我们来看看民工叔徐飞在 QConf 分享的主题:单页应用的数据流方案探索

2 内容概要

文中主要介绍了响应式编程理念,提到的观点,主要有:

  1. Reactive 数据封装
  2. 数据源,数据变更的归一
  3. 局部与全局状态的归一
  4. 分形思想
  5. action 分散执行
  6. app级别数据处理,推荐前端 Orm

整体来看,核心思路是推荐组件内部完成数据流的处理,不用关心使用了 Redux Mobx 或者 Rxjs,也不用关心这些库是否有全局管理的野心,如果全局管理那就挂载到全局,但组件内部还是局部管理。

最后谈到了 Rxjsxstream 响应式数据流的优势,但并未放出框架,仅仅指点了思想,让一些读者心里痒痒。但现在太多”技术大牛“把”业界会议“当成了打广告,或者工作汇报的机会,所谓授人以鱼不如授人以渔,这篇文章卓尔不群。

3 精读

一切技术都要看业务场景,民工叔的 单页应用数据流方案 解决的是重前端的复杂业务场景,虽然现在前端几乎全部单页化,但单页也不能代表业务数据流是复杂的,比如偏数据展示型的中台单页应用就不适合使用这套方案。

此文讨论的是纯数据流方案,与 Dom 结合的方案可以参考 cyclejs,但这个库主要搭建了 Reactive -> Dom 的桥梁,使用起来还要参考此文的思路。

3.1 响应式数据流是最好的方案吗?

我认为前端数据流方案迭代至今,并不存在比如:面向对象 -> 函数式 -> 响应式,这种进化链路,不同业务场景下都有各自优势。

面向对象

以 Mobx 为代表,轻前端用的较多,因为复杂度集中在后端,前端做好数据展示即可,那么直接拥抱 js 这种基于对象的语言,结合原生 Map Proxy Reflect 将副作用进行到底,开发速度快得飞起。

数据存储方式按照视图形态来,因为视图之间几乎毫无关联,而且特别是数据产品,后端数据量巨大,把数据处理过程搬到前端是不可能的(为了推导出一个视图形态数据,需要动辄几GB的原始数据运算,存储和性能都不适合在前端做)。

函数式

以 Haskell 为代表,金融行业用的比较多,可能原因是金融对数据正确性非常敏感,不仅函数式适合分布式计算,更重要的是无副作用让数据计算更安全可靠。

个人认为最重要的原因是,金融行业本来很少有副作用,像前端天天与 Dom 打交道的,副作用完全逃不了。

响应式

以 Rxjs 为代表,重前端更适合使用。对于 React native 等 App 级别的开发,考虑到数据一致性(比如修改昵称后回退到文章详情,需同步作者修改后的昵称),优先考虑原始类型存储,更适合抽象出前端 Orm 作为数据源。

其实 Orm 作为数据源,面向对象也很适合,但响应式编程的高层次抽象,使其对数据源、数据变动的依赖可插拔,中等规模使用大对象作为数据源,App 级别使用 Orm 作为数据源,因地制宜。

3.2 分形思想

分形思想即充血组件的升级版,特点是同时支持贫血组件的被外部控制能力。

分形的优点

分形保证了两点:

  1. 组件和数据流融为整体,与外部数据流隔离,甚至将数据处理也融合在数据管道中,便于调试。
  2. 便于组件复用,因为数据流作为组件的一部分。

如果结合文中的 本地状态 概念,局部数据也放在全局,就出现了第三点好处:

  1. 创建局部数据等于创建了全局数据,这样代码调试可局部,可整体,更加灵活。

本地状态 可以参考 dva 框架的设计,如果没有全局 Redux 就创建一个,否则就挂载到全局 Redux 上。

分形的缺点

对于聊天室或者在线IDE等,全局数据居多,很多交叉绑定的情况,就不适合分形思想,反而纯 Redux 思想更合适。

3.3 数据形态,是原始数据还是视图数据?

我认为这也是分业务场景,文章提到不应该太偏向视图结构数据,是有道理的,意思是说,在适合原始结构数据时,就不要倾向于视图结构数据了。但有必要补充一下,在后端做了大量工作的中台场景,前端数据层非常薄,同时拿到的数据也是后端服务集群计算后的离线数据,显然原始数据结构不可能放在前端,这时候就不要使用原始数据存储了。

3.4 从原始数据到视图数据的处理过程放在哪

文中推荐放在 View 中处理,因为考虑到不想增加额外的 Store,但不知道这个 Store 是否包含组件局部的 Store。业务组件推荐使用内部数据流操作,但最终还是会将视图数据存在全局 Store 中,只是对组件而言,是局部的,对项目而言是全局的,而且这样对特定的情况,比如其他组件复用数据变更的监听可以支持到。

总结

我们到头来还是没有提供一个完美的解决方案,但提供了一个完整的思路,即在不同场景下,如何选择最合适的数据流方案。

最后,不要盲目选型,就像上面提到的,这套方案对复杂场景非常棒,但也许你的业务完全不适合。不要纠结于文中为何没有给出系统化解决方案的 Coding 库,我们需要了解响应式数据流的优势,同时要看清自己的业务场景,打造一套合适的数据流方案。

最后的最后,如有不错的数据流方案,解决了特定场景的痛点,欢迎留言。

如果你想参与讨论,请点击这里,每周都有新的主题,每周五发布。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant