Rxjs 数据流实践

遇到的困难

目前公司的核心项目DCE(DaoCloud Enterprise)是一个非常复杂的SPA,它的复杂性主要体现在数据和交互逻辑两方面上。在数据方面,DCE管理着相当多的数据。在交互逻辑方面,DCE中的每一个操作几乎都是牵一发而动全身。但是交互逻辑的复杂归根结底是表现为数据的复杂,因为每一次交互,本质上都是在处理数据。为了保证数据的正确性,原来使用angularjs写的DCE中有很多数据处理、检测数据变化的代码,结果导致应用非常的卡顿。

复杂数据SPA应用的难点

数据来源多

DCE的数据主要有以下几个来源:

  1. 后端和Docker的API
    API是数据的主要来源,应用、服务、容器、存储、租户等信息都是通过API获取的。
  2. Docker API 所使用的 stream
    stream 也是一个通信协议。Docker使用这个协议来通知容器状态的变化。
  3. 后端的Socker
    后端通过socket来通知应用等数据的状态的变化。
  4. localStorage
    保存用户信息,租户信息等。

数据来源多导致了两个问题:

  1. 复用处理数据的逻辑比较困难:
    比如容器列表这个数据。获取的时候我们需要一段代码来格式化容器列表。但是容器列表之后还会更新,由于更新的逻辑和获取的逻辑不一样,所以就很难再复用之前所使用的代码。

2.获取数据的接口形式不统一:
如今我们调用API时,都会返回一个Promise。但是不是所有的数据来源都能转换成Promise,比如Socket事件,结果就是在获取数据的时候,要先调用API,单后再监听socket事件。结果就是代码的冗余。

数据复杂

DCE数据的复杂还体现在三个方面:

  1. 后端获取的数据不能直接展示,要经过一系列复杂逻辑的格式化
  2. 其中部分格式化逻辑还包括发送请求。
  3. 数据之间还存在着复杂的依赖关系。

数据更新困难

缓存是个很好的想法,但是在一个对数据的实时性要求非常高的应用中,缓存很难做的足够好。
DCE中几乎所有数据都是会被全局使用到的。比如郭应用列表的数据,不仅要在应用列表中显示,也可能在侧边栏统计应用数量的地方要用到。所以说如果一处数据更新了,另一处没有更新,那就很尴尬了。还有就是数据的依赖关系,如果被依赖的数据改变了,此时也要更新依赖的缓存数据。但是实际上很多时候数据的依赖树太深了,有些依赖关系还不是很明显,结果就会忘记更新缓存。

结论

前端开发两大噩梦:状态管理和异步操作,同时以上三个难点也是传统的flux架构难以胜任的原因。Rxjs在这个时候就能很轻而易举的解决这两大困难。

DCE 的 Rxjs 架构图

alpha 为应用所需的顶层数据源,如版本信息,用户信息以及license等,需要这些数据才能进行下一步。
socket 为应用与后端数据实时通信的接口,当后端数据有更新时,通过 socket 发送消息给 hub,通知应用更新。
hub 为整个应用最主要的 observable ,是数据的分发中心,当收到socket的消息时,会及时的通知右侧底层数据源调用相应的接口获取最新的数据,而右侧规模较大的数据则由这些底层数据源 combinelatest 拼接而成,形成一颗单向流动的数据树。

Rxjs解决的困难

  1. 统一了异步和同步的逻辑。解决异步问题。
  2. 数据推送的机制把拉取的操作变成了推送的操作。解决更新问题。
  3. BehaviorSubject 可以缓存数据。解决了状态管理的问题。
坚持原创技术分享,您的支持讲鼓励我继续创作!