Spring Reactor 3.1.0.M3を使用していて、複数のソースからMonoをマージする必要がある使用例があります。 Monoの1つが空のMonoの場合、Zipはエラーなしで失敗することがわかりました。
例:
Mono<String> m1 = Mono.just("A");
Mono<String> m2 = Mono.just("B");
Mono<String> m3 = Mono.empty();
Mono<String> combined = Mono.Zip(strings -> {
StringBuffer sb = new StringBuffer();
for (Object string : strings) {
sb.append((String) string);
}
return sb.toString();
}, m1, m2, m3);
System.out.println("Combined " + combined.block());
M3が追加されると、レスポンスがnullの場合、コンビネータはスキップされます。 m3を削除すると、すべて正常に機能し、「AB」が返されます。空のモノを検出してこれを処理できる方法はありますか?また、キャストする代わりに、combinatorメソッドにオブジェクトのタイプを知らせる方法はありますか?
Zipオペレーターは、このように動作しません。それは実際には直観に反するでしょう:あなたのコードは3つの要素のタプルを期待していて、あなたは2つしか得ていません!?
この場合、あなたが管理し、何も提供されない場合に適切なデフォルト値を決定できるのはあなただけです(null
値はリアクティブストリームの仕様で禁止されていることに注意してください)。
_Mono<String> m1 = Mono.just("A");
Mono<String> m2 = Mono.just("B");
Mono<String> m3 = Mono.empty().defaultIfEmpty("");
Mono<String> combined = Mono.when(m1, m2, m3).map(t -> {
StringBuffer sb = new StringBuffer();
sb.append(t.getT1());
sb.append(t.getT2());
sb.append(t.getT3());
return sb.toString();
});
_
Publisher
タイプの性質に混乱しているようです。以下を参照してください:
monoの1つが空のMonoである場合、Zipはエラーなしで失敗します
そして
したがって、Zip Monoを試してみると、何らかの理由でZip Monoが空の場合、Zipは失敗し、それを防ぐためのコードを挿入することができません。
空のMono
は失敗のケースではありません。値が出力されず、正常に完了しただけです。コードサンプルを変更することで確認できます。
_ combined.subscribe(
s -> System.out.println("element: " + s), // doesn't execute
s -> System.out.println("error: " + s), // doesn't execute
() -> { System.out.println("complete!"); // prints
});
_
したがって、要件に応じて、次のことができます。
defaultIfEmpty
インスタンスにMono
演算子を適用します。信頼できる便利なデフォルト値がある場合defaultIfEmpty
にデフォルト値を使用してMono
演算子を適用するか、combined.switchIfEmpty(Mono.error(...))
でエラーメッセージに変換しますMono.Zip
ソースのエラーまたは空の完了により、他のソースがキャンセルされ、結果のMonoがそれぞれすぐにエラーまたは完了します。
Monoソースが値なしで完了したときに、他のソースの実行を続行したい場合は、Mono.zipDelayErrorが最適です。