Cycle.js 状态管理模型

分形(fractal)

当今前端领域,最流行的状态管理模型毫无疑问是 redux,但遗憾的是,redux 并不是一个分形架构。什么是分形架构:

如果子组件能够以同样的结构,作为一个应用使用,这样的结构就是分形架构。

callbag,一个有趣的规范

push 和 pull 模型

如果你了解 RxJs,在响应式编程中,Observable 和 Obsever 是 push 模型,与之对应的,还有一个 pull 模型:

  • Pull(f(): B:返回一个值。
  • Push(f(x: A): void:响应式的,当有值产生时,会发出一个事件,并携带上这个值。订阅了该事件的观察者(Observer)将获得反馈。

JavaScript 中的 Math.random()window.outerHeight 等都是 pull 模型:

const height = window.outerHeight();
// 或者是迭代器写法
function* getWindowHeight() {
while(true) {
yield window.outerHeight;
}
}
var iter = getWindowHeight()
iter.next()

pull 模型包含两个部分:

  • 生产者 :负责生产数据,是数据源
  • 消费者 :负责消费数据,是数据的使用方

在 pull 模型中,数据是 按需索取 的。

再通过 RxJs 看一个 push 模型的例子:

Rx.Observable
.fromEvent(document, 'click')
.map(event => `Event time: ${event.timeStamp}`)
.subscribe(function observer(val) {
console.log(val);
})

push 模型的组成包含了两个部分:

  • 可观察(可监听)对象 :是数据来源
  • 观察者(监听者):是数据的使用方

与 pull 模型不同,观察者 不能主动索取数据 ,而是观察数据源,当数据源有数据时,才可消费和使用。

push 模型有这么一些优点:

  • 高度复用的可观察对象 :通过对源可观察对象使用不同的运算子,可构建出新的可观察对象。
  • 延迟执行 :可观察对象只有被观察者订阅,才会派发数据。
  • 声明式、描述未来的代码 :我们只用声明数据源和数据消费方式,而不用关心数据交付时的细节。

Cycle.js 的作者 Andre Staltz 长久以来面对一个问题,Cycle.js 及其推荐使用的响应式编程库 xstream 都是 push 模型的,这让框架的模型和业务代码都受益于 push 模型的优点。但是,实际项目中,我们还是有不少 pull 模型下的需求,Andre Staltz 也开了一个 issue ,讨论如何更好的使用代码描述 pull 模型。

2017.03 - 2017.08 的学习总结

从今年三月份开始,我在前端的学习路径是:

  1. JavaScript 函数式编程(Lisp、Haskell 开发者轻喷)
  2. 函数响应式编程:FRP,这一块主要是以学习 Rxjs 为主
  3. 函数式编程和函数响应式编程的应用:这一块主要是以学习 Cycle.js 为主

斯坦福机器学习笔记

系列文章已发布至 Gitbook

本书为斯坦福吴恩达教授的在 coursera 上的 机器学习公开课 的知识笔记,涵盖了大部分课上涉及到的知识点和内容,因为篇幅有限,部分公式的推导没有记录在案,但推荐大家还是在草稿本上演算一遍,加深印象,知其然还要知其所以然。

本书涉及到的程序代码均放在了我个人的 github 上,采用了 python 实现,大部分代码都是相关学习算法的完整实现和测试。我没有放这门课程的 homework 代码,原因是 homework 布置的编程作业是填空式的作业,而完整实现一个算法虽然历经更多坎坷,但更有助于检验自己对算法理解和掌握程度。