我正在从Kotlin调用一个Scala类,该类返回Future,我可以对该未来进行Await
private fun scalaFutureInKotlin() {
val future: Future<String> = Future.successful("Hello world from Scala")
val result: String? = Await.result(future, Duration.apply(10, TimeUnit.SECONDS))
println(result)
}
但我真正想要的是能够实现onComplete
回调,并将值传递到KotlinChannel
或Flow
中,以便在另一个coroutine
中使用,这样我就不会阻塞任何线程。
知道如何在Kotlin
中实现Scala Future
的onComplete
功能吗?
根据答案:
从
Scala 2.13
开始,标准库包括scala.jdk.FutureConverters
,它提供Scala到Java的Future
转换(反之亦然(:import scala.jdk.javaapi.FutureConverters import java.util.concurrent.CompletionStage val javaFuture: CompletionStage<Int> = FutureConverters.asJava(scalaFuture)
一旦您获得CompletionStage,您就可以在Kotlin中使用以下选项进行交互:
- 由于kotlin.coroutines提供了在其上定义的CompletionStage.await函数,因此您可以异步等待未来的完成:
// Dependencies:
// implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
// implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.3.9"
import kotlinx.coroutines.future.*
import java.util.concurrent.*
import scala.jdk.javaapi.FutureConverters
private suspend fun scalaFutureInKotlin() {
val future: Future<String> = Future.successful("Hello world from Scala")
val javaFuture: CompletionStage<Int> = FutureConverters.asJava(future)
val result: String? = javaFuture.await() // asynchronous await, function resumes when result is available, callable by suspend function only
println(result)
}
// Examples:
suspend fun main() {
scalaFutureInKotlin()
}
// or for calling from coroutine when not inside suspendable block
fun main() {
val scope = CoroutineScope(Dispatchers.Default)
scope.launch { scalaFutureInKotlin() } // call from inside coroutine
}
- 直接将侦听器添加到CompletionStage:
import java.util.concurrent.*
import scala.jdk.javaapi.FutureConverters
private fun scalaFutureInKotlin() {
val future: Future<String> = Future.successful("Hello world from Scala")
val javaFuture: CompletionStage<Int> = FutureConverters.asJava(future)
javaFuture.thenAccept { result -> // use thenApply if you want to return sth and chain the calls
println(result)
}
}