我在列表中列出了一系列网址。
我想通过调用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")
}
}
}
}
答案 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