我在Scala中有以下代码:
val status: Future[String] = Await.ready(Http(address OK as.String), 1 second)
我正在拨打http
电话,我等了一秒钟的答案。
我被告知阻止使用Await.ready
是不好的做法。
我很好奇我能用什么。
我可以用于理解吗?怎么样?
答案 0 :(得分:3)
阻止异步操作通常很糟糕,否则,为什么要使它异步?
您可以使用Future[T]
的各种实现,例如注册延续以在结果到达时调用。例如,假设您要将String
结果解析为Foo
对象。你会得到:
val result: Future[Foo] = Http(address OK as.String).map {
s => parseJson[Foo](s)
}
请注意,在使用Future[T]
时,除非您同步阻止,否则最终会将它们冒出执行的调用链。
理解可以达到同样的效果:
for {
s <- Http(address OK as.String)
} yield (parseJson[Foo](s))
答案 1 :(得分:2)
使用Await.ready
不是一个好习惯,因为它阻止了。在大多数情况下,您可以撰写和转换期货以达到预期的结果。
但是你可以在绝对必要时使用阻止。以下是关于阻止及其后果的答案When to and when not use blocking
非阻止等待
def afterSomeTime(code: => Unit)(duration: FiniteDuration): Unit = {
someActorSystem.scheduler.scheduleOnce(duration) {
code
}
}
上面的函数会在给定的持续时间后调用代码,你可以使用任何其他的定时器实现代替Akka调度程序
case class TimeoutException(msg: String) extends Exception(msg)
def timeout[T](future: => Future[T])(duration: FiniteDuration)(implicit ec: ExecutionContext): Future[T] = {
val promise = Promise[T]()
future.onComplete(promise tryComplete)
afterSomeTime {
promise tryFailure TimeoutException(s"Future timeout after ${duration.toString()}")
}(duration)
promise.future
}