我有一个简单的sbt项目,我添加了"com.twitter" %% "finagle-http" % "6.33.0"
。我正在关注Twitter Finagle的quickstart指南。我的代码是直接复制粘贴:
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
modification 2
”的情况下打印回复?contentString
”中没有打印modification 1
?如果我在“modification 1
”上设置断点,并使用当前状态评估resp.contentString
,则会根据需要返回网站的HTML。
如何在程序正常运行时进行打印?
答案 0 :(得分:8)
Twitter onSuccess
上Future
方法的签名与标准库Future
上的签名不同 - 而不是:
def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit
你有这个:
def onSuccess(f: (A) ⇒ Unit): Future[A]
即。它返回一个新的未来,返回与旧的未来相同的值,但也执行副作用,而不是仅执行副作用。 (作为旁注,在我看来,这是Twitter未来API比标准库更好的多种方式之一 - 我更喜欢函数参数的返回类型为Unit
并且方法是'n'的事实吨)。
在您的情况下发生的事情是Finagle用于客户端的线程是守护进程的,因此如果您没有明确等待未来的结果,则无法保证JVM在未来满足之前不会退出。更改代码以等待onSuccess
返回的未来结果将使一切按预期工作。