Преобразование Java-будущего в будущее Scala
У меня есть объект Java Future
который я хотел бы преобразовать в Scala Future
.
Глядя на API jucFuture
, я ничего не мог бы использовать, кроме метода isDone
. Это метод блокировки isDone
?
В настоящее время это то, что я имею в виду:
val p = Promise()
if (javaFuture.isDone())
p.success(javaFuture.get)
Есть лучший способ сделать это?
Ответы
Ответ 1
Как просто обернуть его (я предполагаю здесь неявный ExecutionContext здесь):
val scalaFuture = Future {
javaFuture.get
}
EDIT:
Простая стратегия опроса может выглядеть так (java.util.Future = > F):
def pollForResult[T](f: F[T]): Future[T] = Future {
Thread.sleep(500)
f
}.flatMap(f => if (f.isDone) Future { f.get } else pollForResult(f))
Это проверит, будет ли будущее Java осуществляться каждые 500 мс. Очевидно, что полное время блокировки такое же, как и выше (округлено до ближайших 500 мс), но это решение позволит чередовать другие задачи в одном и том же потоке ExecutionContext
.
Ответ 2
Начиная с Scala 2.13
, стандартная библиотека включает scala.jdk.FutureConverters
которая обеспечивает неявные преобразования Java в Scala CompletableFuture/Future
:
import scala.jdk.FutureConverters._
// val javaFuture = java.util.concurrent.CompletableFuture.completedFuture(12)
val scalaFuture = javaFuture.asScala
// scalaFuture: scala.concurrent.Future[Int] = Future(Success(12))
Ответ 3
Используйте FutureConvertors (встроенный утилитой в Scala) для преобразования Java Future в Scala Future.
Рассмотрим пример преобразования Java Future [Int] в Scala Future [Int] ::
import java.util.concurrent.CompletableFuture
import scala.compat.java8.FutureConverters
val javaFuture: java.util.concurrent.Future[Int] = ???
// Some method call which returns Java Future[Int]
val scalaFuture: Future[Int] =
FutureConverters.toScala(CompletableFuture.supplyAsync(new Supplier[Int] {
override def get(): Int = javaFuture.get
}))
Подобное мы можем сделать для любого пользовательского типа вместо Int.
Ответ 4
Для тех, кто читает этот вопрос сейчас, если вы используете Scala 2.13 и выше, используйте:
import scala.jdk.FutureConverters._
И конвертировать, используя completableFuture.asScala
Если вы используете Scala 2.12 и ниже, используйте
import scala.compat.java8.FutureConverters
И конвертировать, используя: toScala(completableFuture)
или completableFuture.toScala
Кроме того, в Scala 2.12 убедитесь, что вы используете правильный артефакт:
org.scala-lang.modules:scala-java8-compat_2.12:0.9.0
Теперь, если по какой-то причине у вас есть Future
, а не CompletableFuture
, что в наши дни должно встречаться редко, следуйте первому из этих ответов: Преобразуйте Java Future в CompletableFuture