【问题标题】:convert `com.ning.http.client.ListenableFuture[Any]` into `scala.concurrent.Future[Any]`将 `com.ning.http.client.ListenableFuture[Any]` 转换为 `scala.concurrent.Future[Any]`
【发布时间】:2016-06-04 19:20:36
【问题描述】:

有什么方法可以将com.ning.http.client.ListenableFuture[A] 类型的变量转换为scala.concurrent.Future[A] 类型

换句话说,函数的内容是什么

def toFuture[A](a: com.ning.http.client.ListenableFuture[A]):scala.concurrent.Future[A] = ???

我具体是A = com.ning.http.client.Response的情况

注意com.ning.http.client.ListenableFuture[A]com.google.common.util.concurrent.ListenableFuture 不同(因此this proposed duplicate 不能解决问题)

【问题讨论】:

    标签: scala future asynchttpclient


    【解决方案1】:

    这个想法与 guava 的 ListenableFuture 相同,但由于签名受到更多限制而受到更多限制。

    首先,您需要获取java.util.concurrent.Executor 以添加回调。由于您的 Scala 代码与 Java 库交互,我建议您基于 Java Executors 定义 scala.concurrent.ExecutorServices 池 - 这样您就可以保留 Executor 和 ExecutorService 的实例,如下所示:

    import java.util.concurrent.Executors
    import scala.concurrent.ExecutionContext
    val executor = Executors.newFixedThreadPool(5) // use it for Java futures
    implicit val executionContext = ExecutionContext.fromExecutor(executor) // use it for Scala futures
    

    如果您想处理不同池中的所有内容,则不需要上述步骤。如果您想使用现有的ExecutionContext,这是我用谷歌搜索的snippet

    然后,要将ListenableFuture 转换为Future,我会做这样的事情(考虑到java.util.concurrent.Future 的一些异常语义):

    def toFuture[A](a: ListenableFuture[A]): Future[A] = {
      val promise = Promise[A]()
      a.addListener(new Runnable {
        def run() = {
          try {
            promise.success(a.get)
          } catch {
            case ex: ExecutionException => promise.failure(ex.getCause)
            case ex => promise.failure(ex)
          }
        }
      }, executor)
      promise.future
    }
    

    【讨论】:

    • 感谢您的回答!我知道object creation impossible, since method run in trait Runnable of type ()Unit is not defined 有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多