在scala中的foreach中使用Thread.sleep()

时间:2014-04-19 03:08:19

标签: web-services scala playframework http-get

我在列表中列出了一系列网址。

我想通过调用WS.url(currurl).get()来获取数据。但是,我想在每个请求之间添加延迟。我可以添加Thread.sleep()吗?还是有另一种方法吗?

 one.foreach {
    currurl => {

  import play.api.libs.ws.WS
  println("using " + currurl)
  val p = WS.url(currurl).get()
  p.onComplete {
    case Success(s) => {
         //do something 
    }
    case Failure(f) => {
      println("failed")
    }
  }
}

}

2 个答案:

答案 0 :(得分:4)

当然,你可以在你的foreach函数中调用Thread.sleep,它会做你期望的。

但是,这将占用一个线程。如果这只是你需要运行的一些实用程序,那么谁在乎,但如果它是你正在尝试编写的某个服务器的一部分,你可能会绑定许多线程,那么你可能想要做更好。你可以做得更好的一种方法是使用Akka(看起来你正在使用Play,所以你已经在使用Akka)来实现延迟 - 编写一个使用scheduler.schedule安排定期接收消息的actor,然后在每次读取消息时处理一个请求。请注意,Akka的调度程序本身会绑定一个线程,但它可以向任意数量的actor发送定期消息。

答案 1 :(得分:1)

您可以使用scalaz-stream

执行此操作
  import org.joda.time.format.DateTimeFormat
  import scala.concurrent.duration._
  import scalaz.stream._
  import scalaz.stream.io._
  import scalaz.concurrent.Task

  type URL = String
  type Fetched = String

  val format = DateTimeFormat.mediumTime()

  val urls: Seq[URL] =
    "http://google.com" :: "http://amazon.com" :: "http://yahoo.com" :: Nil

  val fetchUrl = channel[URL, Fetched] {
    url => Task.delay(s"Fetched " +
      s"url:$url " +
      s"at: ${format.print(System.currentTimeMillis())}")
  }

  val P = Process
  val process =
    (P.awakeEvery(1.second) zipWith P.emitAll(urls))((b, url) => url).
      through(fetchUrl)

  val fetched = process.runLog.run
  fetched.foreach(println)

输出:

Fetched url:http://google.com at: 1:04:25 PM
Fetched url:http://amazon.com at: 1:04:26 PM
Fetched url:http://yahoo.com at: 1:04:27 PM