在Scala文档中,有一个示例如何通过使用promises来选择更快成功的未来。
http://docs.scala-lang.org/overviews/core/futures.html#promises
def first[T](f: Future[T], g: Future[T]): Future[T] = {
val p = promise[T]
f onSuccess {
case x => p.trySuccess(x)
}
g onSuccess {
case x => p.trySuccess(x)
}
p.future
}
此函数返回首先成功的未来,如果其中任何一个失败,它将永远不会完成。
是否有可能以这样一种方式修改它,即使其他未来失败,如果它成功并且如果它们都成功则返回第二个,那么选择更快的一个就像代码现在一样。
答案 0 :(得分:2)
您可以添加:
f onFailure {
case e =>
g onFailure {
case _ =>
p.failure(e)
}
}
当两个期货都失败时,这将失败承诺与f
相同的例外。您可以详细说明这一点,以创建一个例外,记录来自f
和g
的2个例外情况。
答案 1 :(得分:1)
我建议你遵循Alvin Alexander关于Scala期货和承诺的建议here
我相信这是与期货合作的最佳方式
var courses = repository.GetAll();
var studentCourses = courses.Where(x => x.StudentCourses.StudentId == 1234);
答案 2 :(得分:0)
以下是选择最快未来或超时的基本模式,如果它们都太慢:
import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{ Success, Failure }
import akka.actor._
import akka.pattern.after
object GetFastestFutureOrTimeout extends App {
val e = new TimeoutException("TimeoutException")
val system = ActorSystem("GetFastestFutureOrTimeout")
val f1 = Future { Thread.sleep(200); "this is f1" }
val f2 = Future { Thread.sleep(100); "this is f2" }
val timeoutFuture = after(500.milliseconds, using = system.scheduler) { Future.failed(e) }
val f = Future.firstCompletedOf(f1 :: f2 :: timeoutFuture :: Nil)
f onComplete {
case Success(msg) => println(msg)
case Failure(err) => println("An error occured: " + err.getMessage)
}
}
这打印“这是f2”。如果timeoutFuture的超时更改为50,则会打印“发生错误:TimeoutException”。
在引擎盖下,firstCompletedOf使用Promise返回已完成的第一个Future的值,请参阅https://github.com/scala/scala/blob/v2.11.6/src/library/scala/concurrent/Future.scala#L503。
答案 3 :(得分:0)
这是一个基本的实现,用于获取最快的成功响应或失败,如果它们都失败了:
def getFirstSuccessfulResultOrFail[T](requests: List[Future[T]]): Future[T] = {
val p = Promise[T]()
val countDownLatch = AtomicInt(0)
requests.foreach { f =>
f.onComplete {
case Failure(e) => if (countDownLatch.addAndGet(1) == requests.size) p.tryFailure(e)
case Success(s) => p.trySuccess(s)
}
}
p.future
}