kotlinx-coroutines-reactive
使org.reactivestreams.Publisher
拥有awaitXXX
方法:
val person = peopleReactiveRepository.findById(personId).awaitSingle()
如果没有人可以通过人员ID找到,则此调用将抛出NoSuchElementException并且此异常无法直接在用户代码中处理。而Spring MVC ExceptionHandler
无法将此异常转换为用户友好的响应。
java.util.NoSuchElementException: No value received via onNext for awaitSingle
at kotlinx.coroutines.experimental.reactive.AwaitKt$awaitOne$$inlined$suspendCancellableCoroutine$lambda$1.onComplete(Await.kt:131) ~[kotlinx-coroutines-reactive-0.22.1.jar:na]
at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:1327) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.FluxHide$SuppressFuseableSubscriber.onComplete(FluxHide.java:137) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:130) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:96) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at com.mongodb.reactivestreams.client.internal.ObservableToPublisher$1.onComplete(ObservableToPublisher.java:78) ~[mongodb-driver-reactivestreams-1.6.0.jar:na]
我能想出的一种方法如下:
val person = peopleRepository.findById(personId).awaitFirstOrDefault(null)
if (person == null) {
// do something
}
但我不认为这是一种优雅的方式。例如,可以提供名为awaitSingleOptional
的方法。
有没有更好的Kotlin方式来处理这种情况?
答案 0 :(得分:1)
Kotlin中没有标准的Optional
包装器。您可以使用the let
function来处理此类情况:
val person = peopleRepository.findById(personId).awaitFirstOrDefault(null)?.let {
// do
}
如果await-expression的计算结果为默认null
,则let
调用也将计算为null
。如果您需要处理这种情况,可以使用Elvis operator:
.let {...} ?: throw IllegalStateException()
答案 1 :(得分:1)
如果您正在以功能方式进行编程,那么绝对可以使用Optional
包装器。
如果您希望通过函数式编程来解决问题,可以选择具有Arrow和Option数据类型的Try用于此目的。
使用?.let
是另一种选择,但它无法帮助您进行反应式编程。
ReactiveX中还有Notification
类,如果您正在执行Railway Oriented Programming,它将允许您处理错误的情况。
答案 2 :(得分:0)