Преобразование 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