3

我有一个已添加的裸 sbt 项目"com.twitter" %% "finagle-http" % "6.33.0"。我正在关注 Twitter Finagle 的快速入门指南。我的代码是直接复制粘贴:

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.util.{Await, Future}

object Client extends App {
  val client: Service[http.Request, http.Response] = Http.newService("www.scala-lang.org:80")
  val request = http.Request(http.Method.Get, "/")
  request.host = "www.scala-lang.org"
  val response: Future[http.Response] = client(request)
  response.onSuccess { resp: http.Response =>
    println("GET success: " + resp) 
    println(resp.contentString)    // modification 1
  }
  Await.ready(response)
  println("needed this")           // modification 2
}

没有“ modification 2”,我根本没有输出。加上这个println,我得到

needed this
GET success: Response("HTTP/1.1 Status(200)")

Process finished with exit code 0
  1. 为什么没有“ modification 2”的响应打印?
  2. 为什么没有contentString打印出" modification 1"?

如果我在“”上设置断点,并使用当前状态modification 1进行评估,则网站的 HTML 将根据需要返回。resp.contentString

如何在程序正常运行时打印它?

4

1 回答 1

8

onSuccessTwitter 上的方法签名Future与标准库上的不同——而Future不是这样:

def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit

你有这个:

def onSuccess(f: (A) ⇒ Unit): Future[A]

即它返回一个新的未来,它返回与旧未来相同的值,但也执行副作用,而不是仅仅执行副作用。(附带说明一下,在我看来,这是 Twitter 未来 API 比标准库更好的众多方式之一——我更喜欢函数参数的返回类型Unit和方法不是的事实)。

在您的情况下发生的情况是 Finagle 用于客户端的线程已被守护,因此如果您没有明确等待未来的结果,则无法保证 JVM 在满足未来之前不会退出。更改代码以等待返回的未来结果onSuccess将使一切按预期工作。

于 2016-02-06T10:46:55.643 回答