我正在围绕java库编写一个小的scala包装器.
java库有一个QueryExecutor对象,暴露了2个方法:
在这种情况下,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)