ECMAScript的Observable提案
在JavaScript,Observables很大程度上是通过诸如RxJS和Bacon.js这样的库流行起来的。JafarHusain,一个Netflix的技术总监,函数式编程的长期拥护者,同时也是TC39的成员,制定了一份提案用于在js语言核心功能中引入Observables。在编写本文的时候,Observables提案处于stage1状态,但已被标记为准备移到stage2状态。
Observable和observer API
在提案里,Observable
成为了一个新的内置对象,用于处理事件流。Observable
构造函数接收一个用于定于事件流的回调函数。在下面的例子里,我们的observable返回了一个仅包含值1
和2
的事件流。observable.next
方法可以用于往观察流里面添加事件。
|
|
我们可以使用observer.error
来报告流处理过程中发生的错误。
|
|
我们可以使用observer.complete
来标识一个流已经处理结束。
|
|
传入Observable
构造函数的回调可以返回一个清理函数来释放我们的可观察对象。这在需要移除事件监听器、清除timeout和类似的清理工作时会很有用。下面的这个可观察对象比上面那个来得有趣。它跟踪用户在屏幕上移动光标时鼠标相对于页面的位置,然后在这一过程中产生一个描述光标在页面位置的事件流。
|
|
为了订阅一个可观察事件流,我们仅需调用可观察对象实例的Observable#subscribe
方法。这么做将调用上例代码中传入Observable
构造函数的回调函数,绑定事件监听器并且开始事件流。移动鼠标现在会引起事件被触发进事件流。
|
|
Subscription#unsubscribe
Observable#subscribe
返回一个可以让我们unsubscribe
的对象,同时如果存在清理函数则执行它。当我们不在关注可观察流的事件时,我们可以取消订阅,并且让可观察对象清理自身。
|
|
Observable.of
Observable.of(...items)
是一个简单的静态工具函数,用于从提供的items
新建一个Observable
对象。然后当Observable#subscribe
调用的时候会同步分发这些items
。
|
|
我们可以认为如下的代码是Observable.of
的简化实现:对于给定的值我们返回一个同步流。
|
|
Observable.from
这个静态方法将给定参数转为一个Observable
对象。如果给定的Object
拥有一个Symbol.observable
,则返回调用该方法的结果。
|
|
如果给定参数没有实现Symbol.observable
方法,则假定该对象是可遍历的。这将返回该可遍历对象的一个同步Observable
序列。
|
|
在这种情形下,Observable.from
与Observable.of
类似。我们可以认为如下是Observable.from
的简化实现。
|
|
总结
注意这个提案仍然处于早期阶段,但是它将为原生JavaScript级别的函数式编程打下基础。最终,它也许会提供Observable#filter
或者Observable#map
事件流的能力,允许我们只关注我们想要监听的那一类型事件。
同时,随着我们持续关注这一模式,让规范自然而然地逐渐演化,用户群体也可以选择自己实现它。你可以在GitHub仓库上找到当前版本规范的一个polyfill,但是如果你想在浏览器的DevTools里把玩一下你得删掉export
关键字。