博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RxJS的另外四种实现方式(五)——使用生成器实现
阅读量:6238 次
发布时间:2019-06-22

本文共 3343 字,大约阅读时间需要 11 分钟。

hot3.png

接上一篇

js的生成器一般情况下使用场景很少,开发者接触的不是很多。不了解的可以先行查看js语法了解。

这里把其中的执行顺序图解一下

调用方                                                                 数据源next(value)--------------------------------------->              开始执行生成器函数体            <-------------------------------------------------yield value2next(value3)--------------------------------------->            <-------------------------------------------------yield value4next(value5)--------------------------------------->            <-------------------------------------------------return value6

以上是正常返回最后值的过程,也可以永远不return,变成一个无限生成数据的过程。 另一种情况是提前终止

调用方                                                                 数据源next(value)--------------------------------------->              开始执行生成器函数体            <-------------------------------------------------yield value2next(value3)--------------------------------------->            <-------------------------------------------------yield value4return()--------------------------------------->

这种情况下相当于主动关闭生成器。 可以向数据源的函数发出错误:

调用方                                                                 数据源next(value)--------------------------------------->              开始执行生成器函数体            <-------------------------------------------------yield value2next(value3)--------------------------------------->            <-------------------------------------------------try catchthrow(err)

以上各种行为都可以对应Rx,那么生成器和Rx的最大区别是什么呢?

就是谁是主动方,谁是被动方。在生成器中,调用方是主动方,相当于主动pull数据,而Rx中,数据源是主动方,相当于主动push数据。(这里和Rx中的推拉模式有区别)

那么如何使用生成器实现Rx呢?其实你估计已经想到了,就是反过来即可:

Observable                                                    Observernext(value)--------------------------------------->              开始执行生成器函数体            <-------------------------------------------------yield value2(得到返回值是value3)next(value3)--------------------------------------->            <-------------------------------------------------yield value4(返回值是value5)next(value5)--------------------------------------->            <-------------------------------------------------return value6()done==true

于是我们就得到了由Observable主动推送过来的数据了。

我们还是以interval举例

exports.interval = period => sink => {    if (sink.next().done) return noop    let i = 0;    const id = setInterval(() => sink.next(i++).done && clearInterval(id), period)    return () => clearInterval(id)}

这里传入的sink就是迭代器实例,我们主动调用next发送数据 这里我们判断了next函数的返回值里面的done属性,如果Observer主动取消订阅了(在生成器函数里面执行了return语句)那么done就为true

下面是filter操作符:

function* _filter(sink, f) {    for (let done = sink.next().done; !done;) {        let x = yield 0        if (x === _done) break        if (f(x)) done = sink.next(x).done    }    sink.next(_done)    sink.return()}exports.filter = f => source => sink => source(_filter(sink, f))

_done是一个Symbol,用来表示Observable的complete事件 _filter是一个生成器,调用它时传入下一级的迭代器(Observer) yeild 0 不断获取上一级的Observable的数据,一旦收到_done,立即跳出循环,并将_done传入sink中。

最后是实现Subscriber

function* subscribe(n, e, c) {    while (true) {        try {            let result = yield 0            while (result !== _done) {                if (n(result) === _done) return                result = yield 0            }            c && c()        } catch (err) {            e && e(err)        }    }}exports.subscribe = subscribe

是一个死循环,直到收到_done,或者抛出异常。 至此,我们的Rx的基本功能已经实现,由于生成器的性能较差,所以本人没有花很多时间去完善各种操作符,只作为一种可以实现的方式展示出来。

下一篇我们介绍最后一种实现方法。

转载于:https://my.oschina.net/langhuihui/blog/2120113

你可能感兴趣的文章
HAProxy安装使用
查看>>
Serving websites from svn checkout considered harmful
查看>>
Java中Split函数的用法技巧
查看>>
iOS
查看>>
xenserver introduce “Local Storage”
查看>>
25万个虚拟机的实验环境 -VMworld 2011 动手实验室内幕曝光
查看>>
Supporting Python 3——不使用2to3转换支持Python 2和Python 3
查看>>
分布式存储系统MogileFS(一)之基本概念
查看>>
Zabbix宏使用及用户自定义监控
查看>>
网络社交如何保护个人隐私?做好这4步
查看>>
mysqlbinlog 命令筛选时间段某表操作记录
查看>>
python 简单擦错误记录
查看>>
css float
查看>>
SQL*Plus中的Echo
查看>>
云计算技术的产生、概念、原理和前景
查看>>
test
查看>>
将自己的项目部署在github上
查看>>
oracle 启动关闭周期
查看>>
【经典数据结构】B树与B+树
查看>>
c++学习 定位new表达式
查看>>