You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何将CompletableFuture<Optional<T>>转换为Flow<T?>

CompletableFuture<Optional> 转 Flow<T?> 实现方案

问题现状

最初尝试基于Reactor的Mono做中转实现类型转换,代码如下:

fun <T> CompletableFuture<Optional<T>>.asFlowOfNullable(): Flow<T?> =
    this.toMono().map { if (it.isPresent) it.get() else null }.asFlow()

上述代码运行报错,根因是asFlow()方法不支持可空类型的参数。

方案迭代

第一版实现(存在阻塞缺陷)

最初的手写调整方案如下,额外封装了Optional转可空的通用扩展:

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import java.util.Optional
import java.util.concurrent.CompletableFuture

fun <T> Optional<T>.orNull(): T? = orElse(null)

fun <T> CompletableFuture<Optional<T>>.asFlowOfNullable(): Flow<T?> = flowOf(this.join().orNull())

基于该实现可配合Axon的queryOptionalKotlin扩展做业务封装:

inline fun <reified R, reified Q> findById(q: Q, qgw: QueryGateway): Flow<R?> {
    return qgw.queryOptional<R, Q>(q).asFlowOfNullable()
}

注意:该方案存在严重的性能缺陷,CompletableFuture.join()是同步阻塞方法,会直接阻塞当前协程运行的线程,不符合协程非阻塞的设计原则,不推荐生产环境使用。

最终非阻塞实现

修复阻塞问题后的方案由@Joffrey提供,核心是利用JDK CompletableFuture转协程Deferred的官方扩展,全程非阻塞:

fun <T> Optional<T>.orNull(): T? = orElse(null)

fun <T> CompletableFuture<Optional<T>>.asDeferredOfNullable(): Deferred<T?> = thenApply { it.orNull() }.asDeferred()

如果业务场景确实需要返回Flow<T?>类型,可基于上述Deferred做一层轻量转换:

import kotlinx.coroutines.flow.asFlow

fun <T> CompletableFuture<Optional<T>>.asFlowOfNullable(): Flow<T?> = asDeferredOfNullable().asFlow()

内容的提问来源于stack exchange,提问作者Matthew Adams

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 15:48:02