reactive-programming - 两个 Mono 与条件的组合
问题描述
我想Mono
根据某些条件组合结果形式二。两者Mono
都是WebClient
调用的结果:
- 第一个是期望快速响应的单个呼叫。
- 第二个是多个响应缓慢的呼叫的组合。
Mono
如果第一个结果的结果满足某些条件,则“取消”第二个的想法可以节省时间并避免不必要的网络调用。如果第一个Mono
结果不够zip
用第二个Mono
。
一个 Kotlin 代码示例来解释我的想法:
fun getResult(): Mono<Result> {
val trivialResultMono: Mono<Result> = webClient.getResult()
val nonTrivialResultMono: Mono<Result> = webClient
.getResult()
.flatMap { webClient.getResult1(it) }
.flatMap { webClient.getResult2(it) }
.flatMap { webClient.getResult2(it) }
//here I need to check if trivial result satisfies some condition,
//for example trivialResult.size > 5 if it's true I just return
//trivialResultMono from getResult() function,
//it it's false something like this:
return Mono.zip(trivialResultMono, nonTrivialResultMono) { trivialResult, nonTrivialResult ->
trivialResult + nonTrivialResult
}
}
更新:
为了更清楚,假设 trivialResult 在 1 秒内出现, nonTrivialResult 在 2 秒内出现。我想在 1 秒内得到我的最终结果,trivialResult.size > 5
否则在 2 秒内。
使用 just Mono.zip(trivialResultMono, nonTrivialResultMono)
I 将始终在 2 秒内得到最终结果。
如果使用filter + switchIfEmpty
它将需要 1trivialResult.size > 5
秒,否则需要 3 秒。如果我错了,请纠正我。
解决方案
您可以过滤您的trivialResultMono
和应用switchIfEmpty
运算符
return trivialResultMono
.filter(trivialResult -> trivialResult.size > 5)
.switchIfEmpty(Mono.zip(...))
方法更新merge
:
Mono<Result> zipResultMono = Mono.zip...
return Flux.merge(
trivialResultMono.map(trivialResult -> Tuples.of(1, trivialResult)),
zipResultMono.map(zipResult -> Tuples.of(2, zipResult)))
.filter(tuple ->
(tuple.getT1().equals(1) && tuple.getT2().size > 5) ||
tuple.getT1().equals(2))
.next()
.map(Tuple2::getT2);
如果 zipResult 的大小总是大于 5,您可以跳过转换为 Tuple2
推荐阅读
- angular - 配置生产环境
- javascript - 如何在选择输入中显示模式而不是选项?
- php - 如何在集合 laravel 中也将列设为 Upper 并删除符号 _
- python - 如何在 kivy/python 中创建下拉列表?
- python - 'TypeError:预期的字符串或类似字节的对象',同时尝试使用 BeautifulSoup 从网页获取数字
- android - 如何解决此错误:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 $ 处为 BEGIN_OBJECT
- hql - HQL 查询在使用类似运算符进行搜索时返回空值
- c# - 在 Form_FormClosing 中单击是时,C# 对话框不断弹出
- c - 关于链表和节点插入的基本问题
- d3.js - dc.js 绘制嵌套数据数组的图表