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
。