import scala.concurrent.{Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
import scala.util.Random
object Example1 extends App {
println("starting calculation ...")
val f = Future {
sleep(Random.nextInt(500))
42
}
println("before onComplete")
f.onComplete {
case Success(value) => println(s"Got the callback, meaning = $value")
case Failure(e) => e.printStackTrace
}
sleep(2000)
}
使用Await.ready,我们可以等待10秒钟,如果将来还没有完成,它将抛出TimeoutException。但是Await.ready正在阻止。如上例所示,使用回调时等待10秒的最佳方法是什么?(不使用Akka之类的框架)
答案 0 :(得分:2)
令人难以置信,但是scala标准库不包含此功能:(
可以使用其他Future
实现方式-类似于com.twitter.util.Future
或scalaz.concurrent.Future
,但是使用标准scala Future
时,您无法立即使用它。
您可以自己实现它,但这看起来有点难看:(
object FutureCancellator {
val scheduler = ??? // You can use whatever scheduler available within your system - like akka scheduler or whatever, or roll your own, based on a timer thread.
class Within[T](val f: Future[T]) extends AnyVal {
def within(d: Duration): Future[T] = {
val timeout: Future[T] = scheduler.after(d) { _ =>
throw new TimeoutException(e)
}
Future.firstCompletedOf(f, timeout)
}
}
}
现在,您可以执行以下操作:
import FutureCancellator._
import scala.concurrent.duration._
someFuture
.within(10 seconds)
.onComplete {
case Success(foo) => println(s"got $foo")
case Failure(t: TimeoutException) => println("timeout")
case Failure(e) => e.printStackTrace
}