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評価resp.contentStringすると、Web サイトの HTML が期待どおりに返されます。

プログラムが正常に実行されている間にそれを印刷するにはどうすればよいですか?

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 future API が標準ライブラリよりも優れている多くの方法の 1 つです。私は、関数の引数の戻り値の型がUnitであることと、メソッドの戻り値の型がそうでないことの両方を好みます)。

あなたの場合、Finagleがクライアントに使用しているスレッドがデーモン化されているため、未来の結果を明示的に待機しない場合、その未来が満たされる前にJVMが終了しないという保証はありません。によって返される未来の結果を待つようにコードを変更するonSuccessと、すべてが期待どおりに機能します。

于 2016-02-06T10:46:55.643 に答える