java - 在不阻塞线程的情况下等待 Kotlin 协程中的 Java 5 Futures
问题描述
我有一个suspend
函数,我想从中返回 Java 5 的结果Future
。未来对象来自另一个库Firebase Cloud Firestore- Admin SDK for Java,并提供阻塞调用get()
来检索所述未来的结果。
我的功能看起来像这样-
suspend fun getPrefix(messageCreateEvent: MessageCreateEvent): String {
val snapshot = db.collection("prefixes")
.document(messageCreateEvent.guildId.get().asString())
.get() //This returns a future
.get() //Retrieves the future's result (Blocks thread; IDE gives warning)
//Return the prefix
return if (snapshot.exists())
snapshot.getString("prefix") ?: DEFAULT_PREFIX
else DEFAULT_PREFIX
}
我考虑过的解决方案
我考虑的第一件事是寻找kotlinx.coroutine
扩展来连接未来。虽然存在扩展,但它们仅适用于CompletionStatge
. 所以我决定把未来包装成一个()——
val snapshot = CompleteableFuture.supplyAsync {
db.collection("prefixes")
.document(messageCreateEvent.guildId.get().asString())
.get() // This returns a future
.get() // Get the result
}.await()
我非常缺乏经验,不确定这是否是正确的解决方案。我在一个编程社区上询问了我的问题,有人建议我使用Deferred
-
val deferred = CompletableDeferred<DocumentSnapshot>()
val future = db.collection("prefixes")
.document(messageCreateEvent.guildId.get().asString())
.get()
future.addListener(
Runnable { deferred.complete(future.get()) },
ForkJoinPool.commonPool()
)
val snapshot = deferred.await()
我已经花了相当长的时间来寻找一种将未来连接到协同程序的方法,甚至没有类似的问题。通过,如果这个问题得到重复标记,我不会感到惊讶。
解决方案
您可以使用它kotlinx-coroutines-guava
来执行此操作
首先转换ApiFuture
为ListenableFuture
使用,ApiFutureToListenableFuture
然后使用.await
以等待 listenableFuture 完成而不阻塞线程。
ApiFutureToListenableFuture(this).await()
推荐阅读
- ruby-on-rails - haml 中的 form_tag 创建没有输入的表单
- reactjs - fetch后在react组件中获取重复元素更多
- r - 在 Shiny 中创建多个内联输入组
- php - PHP 警告:mysqli::__construct(): (HY000/2002): 没有这样的文件或目录 (Debian GNU/Linux 9)
- c++ - 无法在 C++ 中生成一副纸牌
- php - WooCommerce 根据特定分类获取产品
- ssis - 运行 64 位时 SSIS 2017 意外终止
- python - 多处理中的 numpy.random 种子
- mongodb - Dockerfile > RUN mongoimport => 失败:连接到数据库服务器时出错:没有可访问的服务器
- javascript - 完成对象数组 reverse() 和 sort() 按钮,使其在按下时起作用