Reactor Handle
handle
是 Reactor 中一个非常灵活的操作符,它允许你对每个源元素进行处理,并可以选择性地发出零个或多个元素。它既可以用于映射(map)也可以用于过滤(filter),因此可以看作是 map
和 filter
的组合。
1. handle
是一个实例方法
handle
是一个实例方法,这意味着它必须链接在一个现有的源(如Flux
或Mono
)上使用,与其他操作符(如map
、filter
、flatMap
)类似。- 例如:
Flux<String> alphabet = Flux.just(-1, 30, 13, 9, 20).handle((i, sink) -> {String letter = alphabet(i);if (letter != null) {sink.next(letter);}});
2. handle
的签名
-
handle
的签名是:Flux<R> handle(BiConsumer<T, SynchronousSink<R>>);
-
它接收一个
BiConsumer
,第一个参数是当前的源元素T
,第二个参数是SynchronousSink<R>
,用于向下游发送处理后的结果。
3. handle
的作用
handle
允许你对每个源元素进行处理,并可以选择性地发出零个或多个元素。- 它既可以用于映射(map)也可以用于过滤(filter),因此可以看作是
map
和filter
的组合。 - 例如,你可以使用
handle
来实现一个“映射 + 过滤 null”的场景,就像mapNotNull
在 Kotlin 中一样。
4. handle
与 map
和 filter
的区别
map
:只用于映射,不进行过滤。如果映射函数返回null
,Reactor 会抛出NullPointerException
。filter
:只用于过滤,不进行映射。如果过滤条件不满足,元素会被丢弃。handle
:结合了map
和filter
的功能,可以灵活处理元素,甚至可以抛出异常或忽略元素。
5. 示例:handle
用于“映射 + 过滤 null”
- 你提到的
alphabet
方法有时会返回null
,但你希望只保留非null
的结果。 - 使用
handle
可以安全地处理这种情况,避免NullPointerException
。
Flux<String> alphabet = Flux.just(-1, 30, 13, 9, 20).handle((i, sink) -> {String letter = alphabet(i);if (letter != null) {sink.next(letter);}});
alphabet.subscribe(System.out::println);
-
输出:
M I T
-
解释:
-1
和30
超出范围,返回null
,因此不会调用sink.next()
。13
、9
、20
在范围内,返回字母M
、I
、T
,并被发送到下游。
6. handle
的优势
- 灵活性:可以同时处理映射、过滤、错误处理等复杂逻辑。
- 安全性:可以避免
NullPointerException
,因为你可以显式检查返回值是否为null
。 - 性能:
handle
是一个轻量级操作符,适合处理简单的映射和过滤逻辑。
7. handle
与 mapNotNull
的关系
- 在 Kotlin 中,
mapNotNull
是一个专门用于“映射 + 过滤 null”的操作符。 - 在 Reactor 中,虽然没有
mapNotNull
,但handle
可以实现类似的功能。 - 例如,你可以使用
handle
来替代mapNotNull
,尤其是在需要处理复杂逻辑时。
8. 总结
handle
是 Reactor 中一个非常灵活的操作符,它允许你对每个源元素进行处理,并可以选择性地发出零个或多个元素。- 它既可以用于映射(map)也可以用于过滤(filter),因此可以看作是
map
和filter
的组合。 - 在处理可能返回
null
的映射函数时,handle
是一个安全且灵活的选择,可以避免NullPointerException
,并提供更细粒度的控制。
参考资料
handle
是一个实例方法,可以链接在现有源上,用于处理每个元素。handle
接收一个BiConsumer
,用于处理每个元素并决定是否发送到下游。handle
可以用于“映射 + 过滤 null”的场景,避免NullPointerException
。