在Scala文档中,有一个例子说明了如何通过使用promise来选择更快成功的未来。
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
}
这个函数返回先成功的未来,如果其中任何一个失败,它永远不会完成。
是否有可能以这样一种方式修改它,即即使其他未来失败,如果第二个成功,则返回第二个,如果两个都成功,则选择更快的一个,就像代码现在所做的那样。
以下是一个基本模式,用于选择最快的未来或在它们都太慢时超时:
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/v 2 . 11 . 6/src/library/Scala/concurrent/Future . Scala # L503。
我建议您遵循阿尔文·亚历山大关于Scala未来和promise的建议
我相信这是处理期货的最佳方式
package futures
import scala.concurrent.{Future => ConcurrentTask} // rename
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
import Utils.sleep
object FutureAsConcurrentTask extends App {
// run some long-running task (task has type Future[Int] in this example)
val task = ConcurrentTask {
Cloud.executeLongRunningTask
}
// whenever the task completes, execute this code
task.onComplete {
case Success(value) => println(s"Got the callback, value = $value")
case Failure(e) => println(s"D'oh! The task failed: ${e.getMessage}")
}
// do your other work
println("A ..."); sleep(100)
println("B ..."); sleep(100)
println("C ..."); sleep(100)
println("D ..."); sleep(100)
println("E ..."); sleep(100)
println("F ..."); sleep(100)
}
您可以添加以下内容:
f onFailure {
case e =>
g onFailure {
case _ =>
p.failure(e)
}
}
当两个期货都失败时,这将使promise失败,例外情况与< code>f相同。如果需要,您可以详细说明这一点,创建一个异常来记录来自< code>f和< code>g的两个异常。
问题内容: 我正在尝试使用字符串方法。但是,如果我将%1,%2等放置在字符串中,则会抛出java.util.UnknownFormatConversionException,指向一个令人困惑的Java源代码片段: 从中我了解到 char是被禁止的。如果是这样,那么我应该对参数占位符使用什么? 我使用Scala 2.8。 问题答案: 尽管所有先前的回答都是正确的,但它们都是Java语言。这是一个Sc
问题内容: 我怎样才能返回一个 函数 副作用的词汇封闭 1 斯卡拉? 例如,我在Go中查看此代码示例: 打印1 2 3 5 8 而且我不知道如何在Scala中编写相同的内容。 1.在Apocalisp评论后更正 问题答案: 稍短一些,您不需要退货。
问题内容: 我想要的只是使用一些并发Set(看起来根本不存在)。Java用于实现该行为。我想在Scala中做类似的事情,所以我创建了Scala HashMap(或Java ConcurrentHashMap)实例,并尝试添加一些元组: 当然,由于Unit是抽象的也是最终的,因此这使编译过程崩溃了。 如何使这项工作?我应该使用/ 代替吗?我必须确保没有人插入任何值。 感谢帮助 问题答案: 您可以只使
问题内容: 我有以下代码: 如您所见,期望使用lambda表达式。 现在,我正在使用Java库,但是该应用程序是用Scala编写的。如何将Scala lambda传递给Java代码? 我尝试了以下方法: 但是编译器抱怨: 问题答案: 错误消息列出了支持的参数类型。其中之一是: 从错误消息中,您可以看到您提供了以下类型: 根据Kafka 1 javadoc (在Kafka 1.1中不存在),定义为:
实际上,恰恰是专有软件的理念--不允许共享或改动软件--是反社会的,也是不道德的,而且也是完全错误的。但是长期以来,软件出版商使人们相信:软件天生就该如此。这种片面的认识禁锢了人们的思维。当他们在谈论如何加强版权或打击盗版时,他们也认定这是天经地义,人们也会毫无异议地接受。 他们的第一个假设就是:软件公司对自己的软件拥有毫无疑问的天然权力,因而可以将权利施加到所有用户身上。(因为如果是天然权力,那