电子书包 android,RxJava学习指南(四)——创建操作符

RxJava学习指南(四)——创建操作符

RxJava学习指南版本:5

整理:陈小默

五、创建操作符

5.1 Create

使用一个函数从头开始创建一个Observable

21870d56f693a796abd850a8acec3423.png

你可以使用Create操作符从头开始创建一个Observable。

其中的onComplete或onError只能被执行一个并且只能被执行一次。

4784cb467d9e7b409d9cbf6ecf5699d8.png

RxJava将这个操作符实现为 create 方法。

建议你在传递给create方法的函数中检查观察者的isUnsubscribed状态,以便在没有观察者的时候,让你的Observable停止发射数据或者做复杂的运算。

示例代码:

Observable.create{

with(it){

if(!isUnsubscribed){

try{

for(iin1until5)onNext(i)

onCompleted()

}catch(e:Exception){

onError(e)

}

}

}

}.subscribe(

{println("Next: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

输出:Next: 1

Next: 2

Next: 3

Next: 4

Sequence complete.

create方法默认不在任何特定的调度器上执行。

5.2 Defer

直到有观察者订阅时才创建Observable,并且为每个观察者创建一个新的Observable

cf0f940ddb5dd573aab36ec1434e8ba1.png

Defer操作符会一直等待直到有观察者订阅它,然后它使用Observable工厂方法生成一个Observable。它对每个观察者都这样做,因此尽管每个订阅者都以为自己订阅的是同一个Observable,事实上每个订阅者获取的是它们自己的单独的数据序列。

在某些情况下,等待直到最后一分钟(就是知道订阅发生时)才生成Observable可以确保Observable包含最新的数据。

d63424dce829b1fcae8c8d336463b121.png

RxJava将这个操作符实现为 defer 方法。这个操作符接受一个你选择的Observable工厂函数作为单个参数。这个函数没有参数,返回一个Observable。

defer方法默认不在任何特定的调度器上执行。

示例程序:

val key="暴走"

val defer=Observable.defer{

Observable.create>{

with(it){

if(!isUnsubscribed){

try{

onNext(query(key))

onCompleted()

}catch(e:Exception){

onError(e)

}

}

}

}

}

defer.subscribe(

{println("List size: ${it.size}")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

5.2.1 switchCase

6a5a53820e61641f12e29c3468fd16bf.png

可选包 rxjava-computation-expressions 中有一个类似的操作符。switchCase操作符有条件的创建并返回一个可能的Observables集合中的一个。

val statement=mapOf>(

0toObservable.from(arrayOf(1,2,3)),

1toObservable.from(arrayOf(7,8,9)))

Statement.switchCase({param},statement).subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

运行结果

param = 0时:Item: 1

Item: 2

Item: 3

Sequence complete

param = 1时:Item: 7

Item: 8

Item: 9

Sequence complete

4133ef84b483afd4d18994c9f09122b0.png

可选包 rxjava-computation-expressions 中还有一个更简单的操作符叫ifThen。这个操作符检查某个条件,然后根据结果,返回原始Observable的镜像,或者返回一个空Observable。

Statement.ifThen({param},Observable.from(arrayOf(1,2,3)))

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

输出结果

param = true时Item: 1

Item: 2

Item: 3

Sequence complete

param = false时Sequence complete

5.3 Empty

创建一个不发射任何数据但是正常终止的Observable

示例程序

Observable.empty().subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")}

)

输出结果equence complete

5.4 Never

创建一个不发射数据也不终止的Observable

示例程序

Observable.never().subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")}

)

该程序不会有任何输出

5.4 Throw

创建一个不发射数据以一个错误终止的Observable

示例代码

Observable.error(RuntimeException()).subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")}

)

5.5 From

将其它种类的对象和数据类型转换为Observable

bb192d2b2d628fdb0228082294e17fe4.png

当你使用Observable时,如果你要处理的数据都可以转换成展现为Observables,而不是需要混合使用Observables和其它类型的数据,会非常方便。这让你在数据流的整个生命周期中,可以使用一组统一的操作符来管理它们。

例如,Iterable可以看成是同步的Observable;Future,可以看成是总是只发射单个数据的Observable。通过显式地将那些数据转换为Observables,你可以像使用Observable一样与它们交互。

因此,大部分ReactiveX实现都提供了将语言特定的对象和数据结构转换为Observables的方法。

8d8181277d7a33d90591d1059ac31853.png

在RxJava中,from操作符可以转换Future、Iterable和数组。对于Iterable和数组,产生的Observable会发射Iterable或数组的每一项数据。

示例代码

Observable.from(arrayOf(1,2,3)).subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

输出Item: 1

Item: 2

Item: 3

Sequence complete

对于Future,它会发射Future.get()方法返回的单个数据。from方法有一个可接受两个可选参数的版本,分别指定超时时长和时间单位。如果过了指定的时长Future还没有返回一个值,这个Observable会发射错误通知并终止。

from默认不在任何特定的调度器上执行。然而你可以将Scheduler作为可选的第二个参数传递给Observable,它会在那个调度器上管理这个Future。

5.5.1 RxJavaAsyncUtil

ac6b0681dad0d1b8b7dc617274986009.png

此外,在可选包 RxJavaAsyncUtil 中,你还可以用下面这些操作符将actions,callables,functions和runnables转换为发射这些动作的执行结果的Observable:fromAction

fromCallable

fromFunc0

fromRunnable

在这个页面 Start 查看关于这些操作符的更多信息。

25cc78ecaf8f9c9ad5825752bac6f37a.png

注意:还有一个可选的StringObservable类中也有一个from方法,它将一个字符流或者一个REader转换为一个发射字节数组或字符串的Observable。

5.5.2 runAsync2

注意:这里与后面start操作符里的runAsync说明重复了

在单独的RxJavaAsyncUtil包中(默认不包含在RxJava中),还有一个runAsync函数。传递一个Action和一个Scheduler给runAsync,它会返回一个StoppableObservable,这个Observable使用Action产生发射的数据项。

传递一个Action和一个Scheduler给runAsync,它返回一个使用这个Action产生数据的StoppableObservable。这个Action接受一个Observable和一个Subscription作为参数,它使用Subscription检查unsubscribed条件,一旦发现条件为真就立即停止发射数据。在任何时候你都可以使用unsubscribe方法手动停止一个StoppableObservable(这会同时取消订阅与这个StoppableObservable关联的Subscription)。

由于runAsync会立即调用Action并开始发射数据,在你创建StoppableObservable之后到你的观察者准备好接受数据之前这段时间里,可能会有一部分数据会丢失。如果这不符合你的要求,可以使用runAsync的一个变体,它也接受一个Subject参数,传递一个ReplaySubject给它,你可以获取其它丢失的数据了。

5.5.3 decode

4bf91dd12b21425216b8fa2ab23e2815.png

StringObservable类不是默认RxJava的一部分,包含一个decode操作符,这个操作符将一个多字节字符流转换为一个发射字节数组的Observable,这些字节数组按照字符的边界划分。

5.6 Interval

Interval操作符创建的Observable每隔固定时间发射一个从0起递增的Long型整数。

4ecf3be4a7a5d20dc2bfb2b010026ec1.png

aea33ab45e3ed74390e7272b2a14c142.png

27353500c57a87c863d704588804908e.png

以下重载增加了一个延时属性。

interval默认在computation调度器上执行

5.7 Just

创建一个发射指定值的Observable

8d74efa06567e1066acef6881846cec8.png

与From不同,Just将每个数据都转换为一个只发射一个数据的Observable。

RxJava将这个操作符实现为just函数,它接受一至九个参数,返回一个按参数列表顺序发射这些数据的Observable。

示例代码:

Observable.just(1,2,3).subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

输出Item: 1

Item: 2

Item: 3

Sequence completeJavadoc: just(item) (还有其它接受二到九个参数的版本)

5.8 Range

创建一个发射特定整数序列的Observable

e978786556bdc0e929e9d9ebf5796d81.png

创建一个Observable,这个Observable会从n开始发射递增的m个数据。如果m为负数,会抛出异常。

range默认不在任何特定的调度器上执行

示例代码:

Observable.range(1,3).subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

运行结果Item: 1

Item: 2

Item: 3

Sequence complete

5.9 Repeat

创建一个发射特定数据重复多次的Observable

14f2dddd4a81a669355dfc25a4bb042e.png

Repeat重复地发射数据。某些实现允许你重复的发射某个数据序列,还有一些允许你限制重复的次数。

33e367abfe7bc7a834dc31d10f18dcd9.png

RxJava将这个操作符实现为repeat方法。它不是创建一个Observable,而是重复发射原始Observable的数据序列,这个序列或者是无限的,或者通过repeat(n)指定重复次数。

repeat操作符默认在trampoline调度器上执行。有一个变体可以通过可选参数指定Scheduler。

示例代码:

Observable.from(arrayOf(1,2,3)).repeat(2)

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

结果Item: 1

Item: 2

Item: 3

Item: 1

Item: 2

Item: 3

Sequence complete

5.9.1 repeatWhen

043ba164512ab643e465056408dbffc6.png

还有一个叫做repeatWhen的操作符,它不是缓存和重放原始Observable的数据序列,而是有条件的重新订阅和发射原来的Observable。

将原始Observable的终止通知(完成或错误)当做一个void数据传递给一个通知处理器,它以此来决定是否要重新订阅和发射原来的Observable。这个通知处理器就像一个Observable操作符,接受一个发射void通知的Observable为输入,返回一个发射void数据(意思是,重新订阅和发射原始Observable)或者直接终止(意思是,使用repeatWhen终止发射数据)的Observable。

repeatWhen操作符默认在trampoline调度器上执行。有一个变体可以通过可选参数指定Scheduler。

5.9.2 doWhile

4091527ec4349676e33049a947e3d479.png

doWhile 属于可选包rxjava-computation-expressions,不是RxJava标准操作符的一部分。doWhile在原始序列的每次重复后检查某个条件,如果满足条件才重复发射。

Statement.doWhile(Observable.just(1,2,3),{param})

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

先循环后判断param

5.9.3 whileDo

e9c8392f93f6beffdc04442dbe4b7f68.png

whileDo 属于可选包rxjava-computation-expressions,不是RxJava标准操作符的一部分。whileDo在原始序列的每次重复前检查某个条件,如果满足条件才重复发射。

Statement.whileDo(Observable.just(1,2,3),{param})

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

先判断param再循环

5.10 Start

返回一个Observable,它发射一个类似于函数声明的值

3b73b12b09cd18fdd52e159eb23a4976.png

编程语言有很多种方法可以从运算结果中获取值,它们的名字一般叫functions, futures, actions, callables, runnables等等。在Start目录下的这组操作符可以让它们表现得像Observable,因此它们可以在Observables调用链中与其它Observable搭配使用。

Start操作符的多种RxJava实现都属于可选的rxjava-async模块。

rxjava-async模块包含start操作符,它接受一个函数作为参数,调用这个函数获取一个值,然后返回一个会发射这个值给后续观察者的Observable。

注意:这个函数只会被执行一次,即使多个观察者订阅这个返回的Observable。

fun func(x:Int,y:Int)=x+y

Async.start{func(a,b)}

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

当a=1,b=2时,返回结果如下Item: 3

Sequence complete

5.10.1 toAsync

788dfbe86de33cf7789a1804f55f45b8.png

rxjava-async模块还包含这几个操作符:toAsync, asyncAction, 和asyncFunc。它们接受一个函数或一个Action作为参数。

对于函数(functions),这个操作符调用这个函数获取一个值,然后返回一个会发射这个值给后续观察者的Observable(和start一样)。对于动作(Action),过程类似,但是没有返回值,在这种情况下,这个操作符在终止前会发射一个null值。

注意:这个函数或动作只会被执行一次,即使多个观察者订阅这个返回的Observable。

5.10.2 startFuture

f3ef0939742475f48ecfc391bd0b59af.png

rxjava-async模块还包含一个startFuture操作符,传递给它一个返回Future的函数,startFuture会立即调用这个函数获取Future对象,然后调用Future的get()方法尝试获取它的值。它返回一个发射这个值给后续观察者的Observable。

val future:Future

Async.startFuture{future}.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

5.10.3 deferFuture

93b7167f7e63e34d9ecdca87c406811c.png

rxjava-async模块还包含一个deferFuture操作符,传递给它一个返回Future的函数(这个Future返回一个Observable),deferFuture返回一个Observable,但是不会调用你提供的函数,直到有观察者订阅它返回的Observable。这时,它立即调用Future的get()方法,然后镜像发射get()方法返回的Observable发射的数据。

用这种方法,你可以在Observables调用链中包含一个返回Observable的Future对象。

val future:Future>

Async.deferFuture{future}.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

5.10.4 fromAction

6b154a911de5036c771de78fd0d8ed64.png

rxjava-async模块还包含一个fromAction操作符,它接受一个Action作为参数,返回一个Observable,一旦Action终止,它发射这个你传递给fromAction的数据。

Async.fromAction({

println("action")

},1)

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

5.10.5 fromCallable

6b154a911de5036c771de78fd0d8ed64.png

rxjava-async模块还包含一个fromCallable操作符,它接受一个Callable作为参数,返回一个发射这个Callable的结果的Observable。

Async.fromCallable{1}

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

5.10.6 fromRunnable

725451a76f61ca305108132ba197cb91.png

rxjava-async模块还包含一个fromRunnable操作符,它接受一个Runnable作为参数,返回一个Observable,一旦Runnable终止,它发射这个你传递给fromRunnable的数据。

Async.fromRunnable({

for(iin0until10)println(i)

},1)

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

上述程序会在循环结束后发射数据

5.10.7 forEachFuture

440844210c69788d7995b56734a889ff.png

rxjava-async模块还包含一个forEachFuture操作符。它其实不算Start操作符的一个变体,而是有一些自己的特点。你传递一些典型的观察者方法(如onNext, onError和onCompleted)给它,Observable会以通常的方式调用它。但是forEachFuture自己返回一个Future并且在get()方法处阻塞,直到原始Observable执行完成,然后它返回,完成还是错误依赖于原始Observable是完成还是错误。

如果你想要一个函数阻塞直到Observable执行完成,可以使用这个操作符。

Async.forEachFuture(Observable.just(1,2,3),

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

5.10.8 runAsync

rxjava-async模块还包含一个runAsync操作符。它很特殊,返回一个叫做StoppableObservable的特殊Observable。

传递一个Action和一个Scheduler给runAsync,它返回一个使用这个Action产生数据的StoppableObservable。这个Action接受一个Observable和一个Subscription作为参数,它使用Subscription检查unsubscribed条件,一旦发现条件为真就立即停止发射数据。在任何时候你都可以使用unsubscribe方法手动停止一个StoppableObservable(这会同时取消订阅与这个StoppableObservable关联的Subscription)。

由于runAsync会立即调用Action并开始发射数据,在你创建StoppableObservable之后到你的观察者准备好接受数据之前这段时间里,可能会有一部分数据会丢失。如果这不符合你的要求,可以使用runAsync的一个变体,它也接受一个Subject参数,传递一个ReplaySubject给它,你可以获取其它丢失的数据了。

在RxJava中还有一个版本的From操作符可以将Future转换为Observable,与start相似。

5.11 Timer

创建一个Observable,它在一个给定的延迟后发射一个0。

0f65f6fc7cae7a2cc206ac3a00bd9a3d.png

timer返回一个Observable,它在延迟一段给定的时间后发射一个简单的数字0。

timer操作符默认在computation调度器上执行。有一个变体可以通过可选参数指定Scheduler。

Observable.timer(1000L,TimeUnit.MILLISECONDS,Schedulers.immediate())

.subscribe(

{println("Item: $it")},

{println("Error: ${it.message}")},

{println("Sequence complete")})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值