Reputation: 13481
I´m invoking from Kotlin a Scala class that return a Future, I can make an Await of that future
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)
}
But what I really want is to being able to implement the onComplete
callback and pass the value into a Kotlin Channel
or Flow
to being used in another coroutine
, so then I dont block any thread.
Any idea how to implement a onComplete
function of a Scala Future
in Kotlin
?
Upvotes: 2
Views: 460
Reputation: 8106
From the answer:
Starting
Scala 2.13
, the standard library includesscala.jdk.FutureConverters
which provides Scala to JavaFuture
conversions (and vice versa):import scala.jdk.javaapi.FutureConverters import java.util.concurrent.CompletionStage val javaFuture: CompletionStage<Int> = FutureConverters.asJava(scalaFuture)
Once you get CompletionStage, you can interop with it in Kotlin with following options:
// 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
}
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)
}
}
Upvotes: 3