Преобразование будущего 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
}

РЕДАКТИРОВАТЬ:

Простая стратегия опроса может выглядеть следующим образом (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,

Начало Scala 2.13 стандартная библиотека включает scala.jdk.FutureConverters который предоставляет Java для Scala CompletableFuture/Future неявные преобразования:

import scala.jdk.FutureConverters.Ops._

// val javaFuture = java.util.concurrent.CompletableFuture.completedFuture(12)
val scalaFuture = javaFuture.asScala
// scalaFuture: scala.concurrent.Future[Int] = Future(Success(12))

Для тех, кто читает этот вопрос сейчас, если вы используете 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

Используйте 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's Future[Int]

val scalaFuture: Future[Int] = 
FutureConverters.toScala(CompletableFuture.supplyAsync(new Supplier[Int] {
      override def get(): Int = javaFuture.get 
    }))

Подобное мы можем сделать для любого пользовательского типа вместо Int.

Другие вопросы по тегам