[英]Convert a Java Future to a Scala Future
我有一個Java Future
對象,我想將其轉換為Scala Future
。
查看jucFuture
API,除了isDone
方法之外,我沒有什么可以使用的。 這是isDone
方法阻塞嗎?
目前我的想法是這樣的:
val p = Promise()
if (javaFuture.isDone())
p.success(javaFuture.get)
有一個更好的方法嗎?
從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))
包裝它怎么樣(我假設這里有一個隱式的 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
的同一線程中交錯。
使用 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 做。
對於現在閱讀此問題的人,如果您使用的是 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.