我正在阅读Scala 2.11.8留档的和
函数在scala.concurrent.Future模块,它说:
def andThen[U](pf: PartialFunction[Try[T], U])
(implicit executor: ExecutionContext): Future[T]
将副作用函数应用于这个未来的结果,并返回一个包含这个未来的结果的新的未来。
这个方法允许强制回调以指定的顺序执行。
请注意,如果其中一个链式第四个回调引发异常,则该异常不会传播到后续的第四个调用。相反,随后的第四次回调将被赋予此未来的原始值。
我不确定< code >和不传播异常到底是什么意思,也没有提供示例。例如,如果我做这样的事情:
Future.successful { throw new RuntimeException("test") } andThen
{ case _ => println("test") }
在斯卡拉REPL,我得到了:
java.lang.RuntimeException: test
... 32 elided
所以异常被传播。有人能提供一个有意义的例子吗?这到底是什么意思?对抛出异常的代码使用< code > then 是否安全?谢谢你。
我认为类型签名是最好的文档。如您所见,并且Then
接受T =
import scala.concurrent.ExecutionContext.Implicits.global
Future{ 2 } andThen {
case _ => throw new RuntimeException("test")
} andThen {
case v ⇒ println("After exception"); println(v)
}
Thread.sleep(500)
这将打印:
java.lang.RuntimeException: test
After exception
Success(2)
再读一遍你的例子。我想你只是忘了线。睡到最后,让未来在节目结束前完成。所以你可能对一切都理解正确。
以后不要<code>抛出<code>异常。成功{}。
下面是正确的方法
Future { throw new RuntimeException("test") } andThen
{ case _ => println("test") }
您可以使用以下代码行了解andRe
的使用
Future.successful { 1 } andThen { case _ => "foo" }
REPL
@ Future.successful { 1 } andThen { case _ => "foo" }
res7: Future[Int] = Success(1)
REPL
@ Future.successful { 1 } andThen { case _ => println("foo") }
foo
res8: Future[Int] = Success(1)
REPL
@ val result = Future.successful { 1 } andThen { case _ => "foo" }
result: Future[Int] = Success(1)
在上面的例子中
我们可以看到,执行了and之后的部分函数,但是忽略了部分函数的返回类型。最后,结果输出是< code>Future的结果,即< code>Future[Int]
这意味着< code>addThen用于在< code>Future完成后立即执行副作用函数。
当未来是失败的
REPL
@ val result = Future { throw new Exception("bar") } andThen { case _ => "foo" }
result: Future[Nothing] = Failure(java.lang.Exception: bar)
REPL
@ val result = Future { throw new Exception("bar") } andThen { case _ => println("foo") }
foo
result: Future[Nothing] = Failure(java.lang.Exception: bar)
当未来是失败时,情况也是如此。和Then之后的代码执行,但和Then之后的代码结果被忽略,最终结果是Future结果。
因此,andThen
用于在 Future 完成后立即运行副作用代码。并且Then
还将最终输出保留为Future
的输出。
这就是andTime
在标准库中的实现方式。
并且位于
未来
类中
def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T] = {
val p = Promise[T]()
onComplete {
case r => try pf.applyOrElse[Try[T], Any](r, Predef.conforms[Try[T]]) finally p complete r
}
p.future
}
1) 将副作用函数应用于此future的结果,并使用此future结果返回一个新future。
对呀
pf
是副作用代码,因为它的输出类型没有被使用(不能被使用)。p.future
是他所说的新未来。Promise
是用前面的Future
结果完成的(看看上面add的实现)
在finally块中,
p完成r
意味着使用p创建新的未来。future
,并使用先前的future结果(即<code>r
2)该方法允许强制以指定的顺序执行回调。
是的。您可以使用多个
and And
调用链接多个回调,并且这些回调按照and And
调用的顺序一个接一个地执行。这与您可以多次使用它来注册多个回调的on完成
方法相比,但这些回调的顺序是不确定的。
3)请注意,如果链接的andAnd回调之一抛出异常,则该异常不会传播到后续的andAnd回调。相反,后续的andAnd回调被赋予这个未来的原始值。
对
r
是上一个未来的结果,给出给pf
(看上面的andAnd代码)
我正在努力理解这个概念。我清楚地了解期货是什么。我对Promises有点困惑。下面的代码片段: 现在,以下两个代码片段之间有什么区别? 和 我对第一个的理解是,p成功将完成与该p相关的未来计算。计算是异步的吗?这与使用 Future 块完成与 Promise p 关联的 Future f 的第二个代码片段有何不同?
我是Scala未来的新手,我还没有找到问题的解决方案。我正在努力实现以下目标(总体描述:努力获取一个酒店列表的客人列表,分别查询每个酒店): < li >对另一个API进行n次调用,每次调用都超时 < li >合并所有结果(将列表转换为包含所有元素的列表) < li >如果单个调用失败,记录错误并返回一个空列表(本质上,在这种情况下,如果我得到部分结果总比没有结果好) < li >理想情况下,如果
我使用scala futures异步提交了1000份工作。我还实现了一个由并发阻塞队列支持的ThrottledExecutionContext,这样它一次最多只能运行100个作业,并将其余的放入队列中。这是一个阻塞操作,因为它涉及调用第三方服务本身。当其中一个抛出异常时,我需要重试整个操作(1000个作业)或者跳过整个批处理。当某些期货仍在运行时,我不能重试。我有办法知道在任何给定的时间点有多少作
我正在使用: Scala 2.10 游戏2.1 目前,我正在使用 类,但我愿意尝试另一个 API。 我很难将多个期货的结果组合成一个列表[(String, String)]。 以下 方法成功地将单个 Future 的结果返回到 HTML 模板: 方法执行 Web 服务 API 调用并返回 Future[play.api.libs.ws.Response]。方法 向 HTML 模板返回 List[(
Java 8的< code > CompletableFuture . allof(CompletableFuture 如果我的一个期货异常完成,那么< code > completablefuture . allof 会在抛出< code>CompletionException之前等待其余期货完成,还是会取消其余期货? 如果它等待所有期货完成,有没有办法让它在任何期货抛出异常并取消剩余期货时立即
在用收益结构组合期货时,有些有副作用,有些没有,我引入了竞争条件,因为取决于副作用的未来并没有将副作用的结果作为论据。 简而言之: 未来b读取由来自未来a的副作用改变的值,但是未来a不明确依赖于未来b的结果,因此可能在b完成读取之前发生。 为了解决这个问题,我的同事引入了一个虚拟函数,将b的结果作为参数并简单地将其丢弃。这样做是为了使依赖显式化。 实际代码如下: 在这种情况下,未来 b 为 带哑参