通过/ ViaMat/to/toMat在Akka Stream

Maa*_*mon 19 akka-stream

有人可以清楚地解释这4种方法之间的区别吗?何时使用每一个更合适?一般来说这组方法的名称是什么?有更多方法可以完成同样的工作吗?链接到scaladoc也可以提供帮助.

-D-

Vla*_*eev 50

所有这些方法都是将两个流连接成一个流所必需的.例如,你可以创建一个Sourcea Source和a Flow,或者你可以创建一个Sinka Flow和a Sink,或者你可以创建一个Flow两个Flows.

为此,有两个基本操作,tovia.前者允许一个连接a Source或a Flow到a Sink,而后者允许连接a Source或a FlowFlow:

source.to(sink)   ->  runnable graph
flow.to(sink)     ->  sink

source.via(flow)  ->  source
flow1.via(flow2)  ->  flow
Run Code Online (Sandbox Code Playgroud)

作为参考,可运行图是完全连接的反应流,其准备好被实现和执行.

*Mat各种操作的版本允许指定如何组合操作中包括的流的具体化值.如您所知,每个流都具有物化值,该值可在物流实现时获得.例如,Source.queue生成一个队列对象,程序的另一部分可以使用该队列对象将元素发送到正在运行的流中.

默认情况下to,via源和流仅保留调用它的流的具体化值,忽略其参数的具体化值:

source.to(sink)    yields   mat.value of source
source.via(flow)   yields   mat.value of source

flow.to(sink)      yields   mat.value of flow
flow1.via(flow2)   yields   mat.value of flow1
Run Code Online (Sandbox Code Playgroud)

但是,有时您需要保留两个物化值或以某种方式组合它们.那Mat就是需要变体的方法.它们允许您指定组合函数,该函数获取两个操作数的实现值并返回组合流的实现值:

source.to(sink)    equivalent to   source.toMat(sink)(Keep.left)
flow1.via(flow2)   equivalent to   flow1.viaMat(flow2)(Keep.left)
Run Code Online (Sandbox Code Playgroud)

例如,要保留两个具体化值,可以使用Keep.both方法,或者如果只需要"右"操作数的mat.value,则可以使用Keep.right方法:

source.toMat(sink)(Keep.both)   yields   a tuple (mat.value of source, mat.value of sink)
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很棒的答案,非常整洁!同时只是为了澄清一点。我觉得奇怪的是 source.to(sink) 中的默认值保留源值(左)。如果水槽是折叠的,我相信我会对折叠的结果感兴趣。在这种情况下,唯一的方法是使用 toMat。实际上我只是看不出默认值是使用左值,而最常见的用例是继续使用正确的值。也许你可以就此发表一些评论。我可能认为它的方式不对。 (2认同)
  • 这是一个很好的答案,除了一些条款不正确。就像“所有这些方法都是将两个流连接到一个流中所必需的”应该是“这些方法是将两个流运算符连接到一个流运算符中所必需的”。并且“每个流都有一个物化值”应该是“每个流运算符都有一个物化值”。原因是,Source、Flow、Sink只是算子,它们组成了最终的Stream (2认同)