响应式学习(三)ProjectReactor

Rxjava2与ProjectReactor 比较

  1. Observable: Rxjava2对比Rxjava1不再接受null。Observable既不实现背压,也不实现Publisher(响应式规范),不推荐作用与大量元素,但其开销小于Flowable、具有toFlowable方法,转换需要选择背压策略。

  2. Flowable: 直接对应Flux,实现了Publisher。

  3. Single: 生成且仅生成一个元素的流,不继承Publisher,使用toFlowable不要背压策略。对比mono更接近CompletableFuture,但是依然是不订阅不执行。

  4. Maybe: 与Mono类型具有相同的语义,但是不实现Publisher,需要时使用toFlowable

  5. Completable: 只能触发onError或onComplete,不能产生onNext,没有实现Publisher接口,toFlowable方法不能生成带onNext的Mono类型。

Reactor 基础操作符

Flux和Mono
响应式规范中Publisher的实现类

Flux可以产生0…N个元素(无限流)

Mono最多生成一个元素(可以轻松的替换CompletableFuture)

Mono对比Flux 跳过了冗余缓冲区和昂贵的同步。

Mono.from(Flux.from(mono))

上述代码实际返回原始mono,并不会执行转换。

defer工厂方法:
会创建一个序列,并在订阅时决定其行为。

Mono<User> requestUserData(String sessionId) {
    return Mono.defer( ()->
        isValidSession(sessionId)         
        ? Mono.fromCallable( () -> requestUser(sessionId) )
        : Mono.error(new RuntimeException("Invalid user session")));
        }

去掉Mono.defer,会将判断执行在订阅之前。

过滤响应式序列:

先开始一个流,停止它来自另一个流的事件响应,代码:

Mono<?> startCommand = ...
Mono<?> stopCommand = ...
Flux<UserEvent> streamOfData = ...

streamofData
    .skipUntilOther(startCommand)
    .takeUnitOther(stopCommand)
    .subscribe(System.out::Print)

映射响应式序列:

Demo
map(Function<T,R>) 操作符之后Flux变成Flux底层实现是cast(Class c)强制转换方法。

收集响应式序列:

Demo
collectList会将Flux处理为Mono 收集操作很耗内存 如果对无限流收集或消耗所有内存。

collectMap 映射为Map<k,T>

collectMultimap -> Map<K,Collection>

repeat() 循环操作

defaultIfEmpty(T) 为Flux和Mono提供默认值

distinct() 仅传递未在流中遇到的元素。高基数会耗尽内存。可以重载

Flux.distinctUntilChanged() 可以适用无限流去重(仅去重和前一个相同的元素)

裁剪响应式序列:

Demo
Flux.any(Predicate) 操作符检查是否至少有一个元素具有所需的属性。

hasElements 操作符检查流中是否包含多个元素(短路逻辑)

any 操作符不仅可以检查元素的相等性,还可以通过Predicate实例来检查其他属性

sort 操作符可以在后台对元素排序,在完成后发出已排序的序列

reduce 自定义裁剪

scan能把中间结果发送到下游

then、thenMany、thenEmpty,在上游完成时完成,这些操作符忽略传入元素,仅重放完成或错误信号,触发新流

合并响应式序列:

Demo
concat 通过向下游转发接收的元素来链接数据源,先消费发送第一个再消费发送第二个

merge 将上游的序列数据合并到一个下游序列,与Concat不同,merge是同时的

zip操作符 将上游所有源的一个元素,组合到一个输出元素中 (取最下元素)

combineLatest 与zip类似 只要有一个元素发送就合并,另一个前一个值

批处理响应式序列:

Demo
buffer 缓冲到容器,结果流的类型为Flux<List>。不是每次都需要小请求时,可以buffer合并处理,缓冲提高效率

windowing 开窗 将元素加入Flux<Flux> 流的元素变成另一个流

group 分组到Flux<GroupedFlux<K,T>>类型的流,一个key对应一个流实例

flatmap系列操作符:

Demo
flatmap可以理解为map+merge两个组合,先转换再返回一个新的流。
不同的变体有: FlatMapSequential 和 concatMap

flatmap和FlatMapSequential会立即订阅,concatMap会等待全部完成再执行子流订阅。

concatMap保留源元素相同的顺序,FlatMapSequential会排序,flatmap不一定

flatmap允许子流元素交错,FlatMapSequential和concatMap不允许。

采样操作符

Demo
sample: 不要所有传入事件就能成功操作的场景

阻塞操作

Demo
toIterable 将Flux转为阻塞Iterable

toStream Flux转为阻塞Stream(Reactor3.2+ 底层调了toIterable)

blockFirst 阻塞当前线程,直到上游发出第一个值或完成流为止

blockLast 阻塞当前线程,直到上游发出最后一个值或完成流为止,如果onError照常抛出。

toIterable,toStream能够用Queue储存先于阻塞完成的事件。

doOn(信号流)操作符

Demo
doOnNext 对Flux或Mono每一个元素执行一些操作。

doOnComplete和doOnError 可以处理相应事件。

doOnSubscribe,doOnRequest,doOnCancel,对对应生命周期事件作出响应。

doOnTerminate(Runnable) 终止时,无论如何都会被调用

doOnEach 处理onError,onSubscribe,onNext,onComplete。

materialize 和 dematerialize 提供信号流与数据流的转换。

大家有好的Demo写法可以留言,实际应用应该参考官方文档:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值