按顺序调用任意数量的WS.url()。get()

时间:2014-06-26 19:55:17

标签: list scala asynchronous future serial-processing

我有一个URL [String],我想按顺序加载和处理(解析,存储到数据库)。

我发现只有固定长度的例子,例如:

    def readUrls = Action {
    implicit request => {
        implicit val context = scala.concurrent.ExecutionContext.Implicits.global

        val url1 = "http://some-website.com"
        val url2 = "http://other-website.com"

        Async {
            for {
                result1 <- WS.url(url1).get()
                result2 <- WS.url(url2).get()
            } yield {
                Ok(result1.body + result2.body)
            }
        }
}

但是我需要处理这只小狗而不是url1和url2:

val urls = List("http://some-website.com", "http://other-website.com")

感谢一大堆提示和建议!

2 个答案:

答案 0 :(得分:3)

如果你想按顺序任意链接FuturefoldLeft应该做的工作:

urls.foldLeft(Future.successful[String]("")){ case (left, nextUrl) =>
    left.flatMap{ aggregatedResult =>
        WS.url(nextUrl).get().map( newResult =>
            aggregatedResult + newResult.body
        )
    }
}

由于您只是将请求主体组合在一起,因此我向foldLeft提供了FutureString的初始值,然后折叠中的每个步骤都将添加到下一个回复机构。

答案 1 :(得分:2)

def executeUrls(urls: List[String]): Future[String] = {
  urls.foldLeft(Future(""))((accumulator, url) => {
      accumulator.flatMap(acc => {
        WS.url(url).get().map(response => {
          acc + response.body
        })
      }
  })
}

这应该是您正在寻找的,请注意它会返回一个新的Future。

编辑:显然LimbSoup更快。