kotlinx-coroutines-reactive如何处理null场景?
kotlinx-coroutines-reactive
使org.reactivestreams.Publisher
拥有awaitXXX
方法:
val person = peopleReactiveRepository.findById(personId).awaitSingle()
如果没有人可以通过人员IDfind,则此调用将引发NoSuchElementException,并且此exception不能直接在用户代码中处理 。 而Spring MVC ExceptionHandler
不能将这个exception转换成用户友好的响应。
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方式来处理这种情况?
如果您是以function方式进行编程,那么您肯定可以使用Optional
包装器。
如果您想通过函数式编程让脚趾受潮,可以选择带有Option和Try数据types的Arrow 。
使用?.let
是另一种选择,但对反应式编程无能为力。
ReactiveX中还有Notification
类,如果你正在进行面向铁路的编程 ,它可以让你处理一个错误的场景。
Kotlin没有标准的Optional
包装。 对于这种情况,您可以使用let
函数 :
val person = peopleRepository.findById(personId).awaitFirstOrDefault(null)?.let { // do }
如果await-expression的计算结果为默认值null
,那么let
调用也会计算为null
。 如果您需要处理这种情况,可以使用Elvis操作员 :
.let {...} ?: throw IllegalStateException()
扩展awaitFirstOrNull()
已经在最近的kotlinx.coroutines
版本0.22.2中可用 。 看到这个PR 。
从发行说明中获取:
awaitFirstOrDefault
:添加了awaitFirstOrDefault
和awaitFirstOrNull
扩展(请参阅@ konrad-kaminski的#224,PR)。