1、修改、改进RxGo包
1.1 简介
ReactiveX是Reactive Extensions的缩写,一般简写为Rx,最初是LINQ的一个扩展,由微软的架构师Erik
Meijer领导的团队开发,在2012年11月开源,Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流,Rx库支持.NET、JavaScript和C++,Rx近几年越来越流行了,现在已经支持几乎全部的流行编程语言了,Rx的大部分语言库由ReactiveX这个组织负责维护,比较流行的有RxJava/RxJS/Rx.NET,社区网站是reactivex.io。中文文档
为什么要重写
Go 语言的 RxGo 看上去就像 go 入门不久的人写的,很怪异。 但 RxJava 库写的很好。
pmlpml/RxGo 模仿 Java 版写了 Go 版本新实现,已基本实现了 Creating Observables 和 Transforming Observables 两类算子。
1.2 课程任务
阅读 ReactiveX 文档。请在 pmlpml/RxGo 基础上,
- 修改、改进它的实现
- 或添加一组新的操作,如 filtering
该库的基本组成:
rxgo.go
给出了基础类型、抽象定义、框架实现、Debug工具等
generators.go
给出了 sourceOperater 的通用实现和具体函数实现
transforms.go
给出了 transOperater 的通用实现和具体函数实现
2、改进版RxGo
2.1 设计说明
此改进版的RxGo包相对原版的pmlpml/RxGo增加了一组filter功能,还对rxgo.go进行了一定程度的修改,在Observable结构体中新增了一组filter的操作符。
//filter model
debounce time.Duration
distinct bool
elementAt int
first bool
ignoreElements bool
last bool
sample chan interface{
}
take int
skip int
而这些新增的操作符的具体功能则会在filter.go文件中实现。
2.2 程序主要函数
此改进版RxGo库包括rxgo.go
, generators.go
, transforms.go
, filter.go
和utility.go
五个文件以及相关的测试文件,而改进的内容主要放在了filter.go中,主要内容如下:
filterOperator
结构体:此结构体用于过滤操作,封装了一个func函数作为接口使用;op
函数:实现了对各个filter操作的初始化以及其报错信息,根据不同的操作来获取数据流;newFilterObservable
函数:用于创建新的filter过滤操作函数,并初始化一些字段;take
函数:判断filter操作中要发射的是哪些数据,用于Take
和TakeLast
函数;skip
函数:判断filter操作中要跳过的是哪些数据,用于Skip
和SkipLast
函数;xxOperator
函数:定义xxOperator
结构体,封装实现该功能的opFunc
,本应是具体过滤操作的具体实现,但因为这些过滤操作的实现已经在op
函数中完成,所以此函数只需要发射数据流即可。Xxxx
函数:即filter操作的具体定义函数,这一类函数的作用是设置过滤操作的相关信息,如果有传入参数,则将传入的参数设置到具体所需的位置。Debounce
:仅在过了一段指定的时间还没发射数据时才发射一个数据Distinct
:抑制(过滤掉)重复的数据项ElementAt
:只发射第N项数据First
:只发射第一项(或者满足某个条件的第一项)数据IgnoreElements
:不发射任何数据Last
:只发射最后一项(或者满足某个条件的最后一项)数据Sample
:定期发射Observable最近发射的数据项Skip
:抑制(跳过)Observable发射的前N项数据SkipLast
:抑制(跳过)Observable发射的后N项数据Take
:只发射bservable发射的前面的N项数据TakeLast
:只发射Observable发射的最后N项数据
2.3 单元测试
此包对主要函数都涉及了相应的单元测试,此处主要讲我所涉及的filter_test.go中的测试函数。
一共有10个单元测试函数,分别对filter操作中的各个具体操作进行测,测试结果如下:
其中比较特殊的是Debounce测试,这里我将debounce的时间设置得很长,最后得到的数组只有头一个元素。
func TestDebounce(t *testing.T) {
var res []int
rxgo.Just(0, 12, 7, 34, 2).Debounce(10000).Subscribe(func(x int