[译] ECMAScript 的 Observables 提案

阅读: 评论:0

[译] ECMAScript 的 Observables 提案

[译] ECMAScript 的 Observables 提案

开始之前

在之前读redux源码时,遇到了关于Symbol.observable的使用,发现从没有看到过这个特性,在国内的技术论坛上逛了许久发现提及此的文章甚少,恰巧今天在摸鱼时发现了一篇聊ECMAScript中新提案observables的文章,故翻译出来加深印象~

原文点此

ECMAScript 中的 Observables 提案

ps: 在下文中将以 ES 代替 ECMAScript

本文介绍的是当前还在ES提案阶段中的observables特性,在下文中通过本文,我们将带你了解该提案,该提案的api,以及一些使用案例

在写下这篇文章的时候,javascriptObservables(观察)正在通过RXJs、Bacon.js等各种类库逐渐普及。Jafar Husain,这位长久以来主张函数式编程的Netfix的技术leader(同时也是TC39的委员)也提出了将observables集成到我们js core中的议案,并且已经通过了stage1(征求意见阶段)且已经确定该提案即将进入stage2(草案阶段)

Observableobserver 的api

在当前提案中,Observable是一个内建的被用来处理事件流的类,Obsservalbe的构造函数可以接受一个定义事件流的回调函数。在接下来的例子中,我们的observable将只返回值为1或者2的事件流。< 方法是用来在observalbe流中添加事件的:

new Observable(observer => {(1);(2);
})
复制代码

我们也可以使用<来记录在流处理时遇到的错误:

new Observable(observer => {(new Error(`Failed to stream events`))
})
复制代码

我们还可以使用observerplete来在流处理完结的时候发出信号:

new Observable(observer => {((2)observerplete()
})
复制代码

传递给我们Observable构造函数的这个回调函数会返回一个清理我们Observable实例的方法,它可以执行清理事件监听,定时任务等等类似的清理任务。举个例子,当然这个例子就要比上面这些有趣的多了,他追踪了用户在移动鼠标时,光标相对于页面的位置,并同时产生了描述当前光标坐标的事件流:

function mouseTracking () {return new Observable(observer => {const handler = ({ pageX, pageY }) => {({ x: pageX, y: pageY })}document.body.addEventListener(`mousemove`, handler)return () =>  {veEventListener(`mousemove`, handler)}})
}复制代码

为了订阅一个Observable的事件流,我们会使用Observable实例上的subscribe方法,这样做会调用我们之前实例化Observable时传入的回调函数,绑定事件的监听,并且启动整个事件流。这样做之后我们就能在移动鼠标的时候在事件流里捕获到它啦:

mouseTracking().subscribe({next({ x, y }) { console.log(`New position: ${ x }, ${ y }`) },error(err) { console.log(`Error: ${ err }`) },complete() { console.log(`Done!`) }
})
复制代码
订阅对象上的 unsubscribe

每次订阅我们都会生成一个订阅对象Subscription,这个订阅对象上会有一个unsubscribe方法让我们用来取消订阅,执行清理方法(我猜大家应该都还记着之前提到的清理函数吧~),当我们不再需要关注观察流里的事件的时候,just unsubscribe it,让我们将其解放吧。

const subscription = mouseTracking().subscribe({next({ x, y }) { console.log(`New position: ${ x }, ${ y }`) },error(err) { console.log(`Error: ${ err }`) },complete() { console.log(`Done!`) }
})subscription.unsubscribe()
复制代码
Observable.of

Observable.of(...items) 是一个简单有效的能帮助我们从提供的items中创建Observable的方法,在使用了Observable.of方法之后,items生成的Observable实例会在调用subscribe的同时生成事件流,返回items中的value

Observable.of(1, 2, 3, 4).subscribe({next(item) { console.log(item) }
})
// <- 1
// <- 2
// <- 3
// <- 4
复制代码

我们甚至可以认为,Observable.of可以理解为跟以下接受一个入参,然后回传事件流的简单例子一样:

Observable.of = (...items) => {return new Observable(observer => {items.forEach(item => {(item)})observerplete()})
}
复制代码
Observable.from

Observable.from静态方法接受一个类型为对象的入参,如果这个对象中有键值为Symbol.observable的方法,那么就会返回这个方法的返回值。

Observable.from({[Symbol.observable]() { return Observable.of(1, 2, 3) }}).subscribe({next(item) { console.log(item) }})
// <- 1
// <- 2
// <- 3
复制代码

当然如果这个传入的对象没有实现Symbol.observable,那么我们就假定其传入的是一个可迭代的元素,Observable.from在这个时候的作用就是将迭代元素遍历并生成一个Observable实例,依次将被遍历的结果放入事件流中:

Observable.from([1, 2, 3]).subscribe({next(item) { console.log(item) }})
// <- 1
// <- 2
// <- 3
复制代码

在这种情况下,我们的Observable.from实现的功能和Observable.of是类似的,据此我们甚至可以这样去理解Observable.from的实现:

Observable.from = value => {if (typeof value[Symbol.observable] === `function`) {return value[Symbol.observable]()}return Observable.of(Array.from(value))
}
复制代码
结语

虽然现在这个提案还在襁褓之中,但是我相信迟早有一天,其会成为javascript的函数式编程的基石。到那天,我相信它还会具有类似filtermap的能力去处理我们的事件流,让我们在庞大的事件流能够仅仅注重我们需要关注的部分就够了

与此同时,我们的代码格式和开发模式也能在其帮助下变得更加的自然和规范,当然你也可以提前使用我们在github上的的polyfill去提前体验它,但是请切记在浏览器环境下删除掉你的export关键字。

多个嘴

作为一个英语不是很好的码农,翻译本文还是有点磕磕碰碰,但是总算还是勉勉强强搞定了,希望能够帮助大家多了解一下这个特性,如有错误麻烦诸位指出一下,最后国际惯例,感谢各位的阅读~

本文发布于:2024-01-30 20:50:49,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170661909022747.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:提案   ECMAScript   Observables
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23