ListenableFuture to scala Future

vpt*_*ron 30 scala future

我正在围绕java库编写一个小的scala包装器.

java库有一个QueryExecutor对象,暴露了2个方法:

  • 执行(查询):结果
  • asyncExecute(query):ListenableFuture [Result]

在这种情况下,ListenableFuture是番石榴库中的一个.

我希望我的scala包装器返回Future [Result]而不是java对象,但我不确定实现它的最佳方法是什么.以下是我提出的两个解决方案:

future {
  executor.execute(query)
}
Run Code Online (Sandbox Code Playgroud)

val p = promise[Result]
val guavaFuture = executor.asyncExecute(query)

Futures.addCallback(guavaFuture, new FutureCallback[Result] {
  def onFailure(t: Throwable) {
    p.failure(t)
  }

  def onSuccess(result: Result) {
    p.success(result)
  }
})

p.future
Run Code Online (Sandbox Code Playgroud)

我想知道哪种方法最好.我的直觉是第一个,当返回一个Future时,仍会阻塞一个线程,而执行调用等待响应,第二个看起来应该是非阻塞.对每种方法的优缺点有何评论?

Kev*_*ght 45

第二个选项是最好的,它保持一切异步.但是......你可以做得更好,并将解决方案抽象为可重用的模式:

implicit class RichListenableFuture[T](lf: ListenableFuture[T]) {
  def asScala: Future[T] = {
    val p = Promise[T]()
    Futures.addCallback(lf, new FutureCallback[T] {
      def onFailure(t: Throwable): Unit = p failure t
      def onSuccess(result: T): Unit    = p success result
    })
    p.future
  }    
}
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地打电话:

executor.asyncExecute(query).asScala
Run Code Online (Sandbox Code Playgroud)

  • 很棒的解决方案.无法相信我的ListenableFuture接口代码与此隐含有多清晰 (2认同)
  • 非常好.使用`Promise [T]`可能更抽象 (2认同)
  • 进口什么? (2认同)