我有列表List<Mono<String>>
。每个Mono代表API调用,我在I / O上等待结果。问题是有些调用没有返回任何内容(空字符串),我需要在那种情况下再次重复它们。
现在看起来像这样:
val firstAskForItemsRetrieved = firstAskForItems.map {
it["statistic"] = (it["statistic"] as Mono<Map<Any, Any>>).block()
it
}
我正在等待所有Monos完成,然后在空身的情况下我重复请求
val secondAskForItem = firstAskForItemsRetrieved
.map {
if ((it["statistic"] as Map<Any, Any>).isEmpty()) {
// repeat request
it["statistic"] = getUserItem(userName) // return Mono
} else
it["statistic"] = Mono.just(it["statistic"])
it
}
然后再次阻止每个项目
val secondAskForItemsRetrieved = secondAskForItems.map {
it["statistic"] = (it["statistic"] as Mono<Map<Any, Any>>).block()
it
}
我觉得这看起来很难看
如果没有手动操作,是否有其他方法可以在Mono中重试呼叫?
是否阻止每个项目以正确的方式获取所有项目?
如何让代码更好?
谢谢。
答案 0 :(得分:5)
我相信有2个运营商可以为您提供帮助:
对于“等待所有Mono
”用例,请查看静态方法when
和zip
。
when
只关心完成,所以即使单声道是空的,只要所有单声道完成,它就会发出onComplete
信号。但是你没有得到数据。zip
关注值并期望所有Monos值得。当所有Monos都被重视时,它会根据传递的Function
组合它们的值。否则它只是完成空。要重试空Mono
,请查看repeatWhenEmpty
。它重新订阅为空Mono
,因此如果Mono
是“冷”,它将重新启动源(例如,发出另一个HTTP请求)。