我是Akka Stream
的新手,从上周开始才开始阅读其文档。我能够理解大多数概念,但发现很难理解Materialized Value
在Akka流中的含义以及它的意义是什么。
[如果有人可以用一个真实的例子向我解释这个例子,这将有助于在Akka Stream中将它与它的用例进行相互关联。
更新
我正在看下面的示例,想了解我们为同一张图获得的两种不同类型的输出。我知道它与Materialized Value
有直接关系,这就是为什么我问上述问题。
implicit val system = ActorSystem("PlainSinkProducerMain")
implicit val materializer = ActorMaterializer()
val source = Source(1 to 10)
val sink = Sink.fold[Int, Int](0)(_ + _)
val runnable: RunnableGraph[Future[Int]] =
source.toMat(sink)(Keep.right)
val sum1: Future[Int] = runnable.run()
val sum2: Future[Int] = runnable.run()
println(sum1.value)
println(sum2.value)
当我运行它时,我得到下面的输出:
None
Some(Success(55))
上面的例子来自docs,下面是它的解释。
由于一个流可以被多次实现,所以对于每个这样的实现,也将重新计算实现值,通常导致每次返回不同的值。在下面的示例中,我们创建了两个在runnable变量中描述的流的正在运行的实例化实例,并且即使我们使用相同的接收器来引用future,这两个实例化也为我们提供了与地图不同的Future。
我在这里有2个问题:1)为什么同一图的2个不同的实例化实例具有2个不同的输出值?尽管物化值是两次计算,但在幕后两个计算都是针对同一图形。
2)为什么返回类型为Some(Success(55))
而不是简单的55
才能成功执行,而返回类型为Failure Exception
会失败? (这可能是愚蠢的问题,但我想了解这个特殊的返回值可以解决/赋予什么问题/优势。)
((对评论的回答)我不确定我是否完全理解您的问题,但是通常流是异步的,并且当您执行run()
来实现流时,它会在另一个线程池中开始执行。因此,即使该流立即终止,也不能保证该值将立即可用。这就是Sink.fold
的结果为Future[T]
的原因-期货意味着“将来”将可用的值,而这正是此处所需要的语义。
“为什么...具有2个不同的值”-正是由于异步性。在您的情况下,碰巧第二个未来已经完成,但是您没有观察到。如果您多次运行该程序,则可能会得到不同的结果。
“为什么退货类型为Some(Success(55))
...”,这就是Scala期货的设计方式。 Future.value
方法返回Option[Try[T]]
,即,如果在调用时未完成将来,则返回None
;如果已完成,则返回Some(v)
,其中v
为Success(result)
或[ C0]。通常,在Scala中,将错误视为值而不是抛出异常时会隐式展开调用堆栈的异常是惯用法。
请注意,使用期货时通常不使用Failure(throwable)
。通常,您可以使用Future.value
,map
或flatMap
之类的组合器来转换Future,然后将最终转换后的Future的结果传递给某个库(例如,作为Web框架中的HTTP响应)或使用[ C0],以获取将来的最终结果或异常,如果将来未在指定的时间范围内完成。