1

我用谷歌搜索了这个,找不到答案。

我想对 Scala/play 框架中的 url 进行 GET 处理,然后对结果做一些事情。如果结果包含我想要的,那么我想用其他参数再次调用它。这可能高达 100 次,所以我不能嵌套几个 WS。我想要一个循环一遍又一遍地执行相同的调用,直到我找到我正在寻找的内容,但是当我将所有这些代码包装在一个循环中时,它不会等待每个调用完成,我理解。但是我该如何解决呢?

var index = 0

val call = WS.url("http://urlToGetSomethingFrom&parameter="+index).get()

for{

response <- call

} yield{

  val something: String = response.json / "name"

  if(something.equals("Eric")){

    //I'm finished, break out

  }else{

    index += 1

    //and then I want to do the same call again
  }

}
4

4 回答 4

1

get()返回一个Future
为了等待它完成,您需要将它Await.result与过期持续时间一起传递。

此处示例:https ://stackoverflow.com/a/16296848/604041

于 2013-05-13T17:46:18.030 回答
1

我认为这与@MartinGotzke 的回答基本相同。我实际上并没有尝试编译这个或任何东西,但希望它会有所帮助......祝你好运!

   /** Keep looking until you find Eric */
   def findEric( index:Int ):Future[Response] = {
        WS.url("http://urlToGetSomethingFrom&parameter="+index).get(
          ).flatMap( 
            (resp) => if( resp.json / "name" == "Eric" ) Promise.successful( resp ).future
                   else findEric( index+1 )
          )
   }


   findEric(0).onComplete( (resp) => { /* whatever it is you really want to do */ } )
于 2013-05-14T00:12:57.067 回答
0

这是 Play 团队为 Techempower 基准测试用 Scala 编写的另一个示例

https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/play-scala/app/controllers/Application.scala#L44

于 2013-05-14T04:03:04.070 回答
0

这是一个不使用阻塞的解决方案。关键是它使用递归调用并且它使用 flatMap 并返回 Promise.pure 以获得所需的结果。

由于它是使用旧的 google 搜索 api 的实际工作示例,它有点复杂,因为有一个标题列表/序列,它被映射并与谓词函数检查。

package controllers

import play.api._
import play.api.mvc._
import play.api.libs.concurrent.Promise
import play.api.libs.json._
import play.api.libs.ws.WS
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object Application extends Controller {

  def index = Action {

    def callWS(index: Int, f: String => Boolean): Future[String] = {
      WS.url("https://ajax.googleapis.com/ajax/services/search/web")
        .withQueryString(("v", "1.0"), ("q", "foo" + index)).get
        .flatMap { response =>
          val titles = (response.json \ "responseData" \ "results" \\ "title")
          titles.map(_.as[String]).find(f(_)).map(Promise.pure(_)).getOrElse(callWS(index + 1, f))
        }
    }

    Async(callWS(0, _.contains("FOO-1")).map(Ok(_)))
  }

}
于 2013-05-13T19:12:20.403 回答