响应式编程(Reactive Programming):事件驱动
CPU多核架构的流行,以及Node.js等全异步软件平台的出现使得异步编程逐渐走上主流舞台,相应的各种异步框架也逐渐出现
回调(Callback)
当我们说到异步的时候,自然而然的就想到Callback,函数调用的结果通过Callback回调返回,在结果返回之前,线程可以继续运行执行其他的操作而不用阻塞。
非常完美,是吗?但是当多个异步操作具有依赖性时,怎么办,这就产生了异步编程中常说的Callback Hell问题,多个Callback嵌套导致代码可读性很差。
- 代码缩进非常难看。
- 回调代码分散在各处,来回跳跃,流程很不清晰。
- 状态分散在多个closure中,难于管理。
代码可读性差只是表现,深层次的原因还是系统建模方法不对。使用Callback就和面向过程一样,将重心放在了操作本身,只能看到眼前,而不能在一个更高的层次上去纵观整个系统。
Future和Promise
Future在Callback的基础上将回调对象化。Future与Callback的区别在于Future引入了完成,未决,错误等标准回调事件,在Future状态改变时以事件的方式通知关注者,这些事件本身就是对象。于是Future将设计者的重点从操作向事件建模方向转变。
事件建模之外,事件在系统中的流动也需要建模,于是就有了Promise,可以将多个事件处理器串联起来,多个依赖的异步操作转化成事件流程的声明,从而一眼就能从代码中看出依赖关系。
Reactive Extension (RX)
RX在Future和Promise的基础上更进了一步,将单一的事件处理扩展到多个先后相关的事件流处理。举个例子,鼠标拖拽事件,是由一个MouseDown事件加多个MouseMove事件以及一个MouseUp事件构成,Promise处理这种情况需要处理器具有状态记住拖拽的阶段。RX将MouseDown和MouseUp这些事件的处理标准化,并且将拖拽阶段的这一共享状态从业务处理器中抽离,而固化到事件处理流程中。RX抽象了大量的事件操作,使得我们可以将重心放到事件流程建模中,而不是具体的一个接一个事件的处理。共享状态从处理器中抽离也有利于业务处理器的重用以及并发处理。
综上,响应式编程中的事件驱动,要求
- 对事件建模
- 对事件流程建模
- 对事件相关性建模