0

play-scala アプリケーションで、WS 呼び出しを行っています。

def getaddresses : ListBuffer[String] = {
   var lb = new ListBuffer[String]()
   var url = "xyz@xyx.com/someapi"

   WS.url(url).get.map {
      response =>
        var emailsSeq = (response.json \\ "email")
        emailsSeq.foreach(lb+=_.toString())
        lb.foreach(println)     //This is filled with values
  }
  lb.foreach(println)           //This is empty
  lb
}

マップ内では、このメソッドによって返される ListBuffer lb に入れたエントリのシーケンスが返されます。問題は、ListBuffer が map{} 内の値を表示するが、その外側には表示されないことです。その結果、空の ListBuffer がメソッドから渡されます。

ws 応答に遅延があるのではないかと考えたので、次のことを試してみましたが、利点はありませんでした。

WS.url(url).withRequestTimeout(10.seconds).get.map {

いっぱいになったリストバッファが返されるのを手伝ってください

4

1 に答える 1

0

ws.url(url).get メソッドは非同期だと思いますので、lb.foreach(println) を呼び出しても何も表示されません。コードの map ブロックの直後に Thread.sleep を追加してみてください。その場合は、getaddresses メソッドを非同期にするか、future/promise を使用する必要があります。

PS: コードをきれいにするためだけに、var の代わりに val を使用する必要があります。

編集:試してみるサンプル:

def getaddresses : ListBuffer[String] = {
   val url = "xyz@xyx.com/someapi"

   val promiseOfAddresses = Promise[ListBuffer[String]]()
   WS.url(url).get.map {
      response =>
        var emailsSeq = (response.json \\ "email")
        promiseOfAddresses.success(emailsSeq) // here you will complete promise with actual value
  }
  val lb = promiseOfAddresses.future.get // here you will obtain future from promise and also get value of future. Method get is blocking and it will wait till promise is fullfiled or failed
  lb.foreach(println)           //This is empty
  lb
}

PS2: おそらく未来/約束に関する最良のヘルプはここにあります: the-neophytes-guide-to-scala-part-9-promises-and-futures-in-practice (私は十分な評判がないので、このブログをググってください) Javaの世界のCompletableFutureのようなものです。ただし、その最善の方法は、常に赤い側にとどまることです (赤 = 非同期関数/メソッド。素敵ですがおしゃべりなブログwhat-c​​olor-is-your-function を参照してください)

于 2016-07-13T08:41:15.837 に答える