我正在玩Akka Streams,并且已经找到了大部分基础知识,但我不清楚如何获取Merge
的结果并进行进一步的操作(map,filter,fold,等等)。
我想修改下面的代码,以便不用将合并传递给接收器,而是可以进一步操作数据。
implicit val materializer = FlowMaterializer()
val items_a = Source(List(10,20,30,40,50))
val items_b = Source(List(60,70,80,90,100))
val sink = ForeachSink(println)
val materialized = FlowGraph { implicit builder =>
import FlowGraphImplicits._
val merge = Merge[Int]("m1")
items_a ~> merge
items_b ~> merge ~> sink
}.run()
我想我的主要问题是我无法弄清楚如何创建一个没有源代码的流组件,而且我无法弄清楚如何在不使用特殊Merge对象的情况下进行合并~>
语法。
编辑:这个问题和答案适用于Akka Streams 0.11
答案 0 :(得分:6)
如果您不关心Merge
随机元素随机下游的语义,那么您可以在concat
上尝试Source
,而不是这样:
items_a.concat(items_b).map(_ * 2).map(_.toString).foreach(println)
这里的不同之处在于,a
中的所有项目都会在b
的任何元素之前首先向下游流动。如果你真的需要Merge
的行为,那么你可以考虑以下内容(请记住,你最终需要一个接收器,但你可以在合并后进行额外的转换):
val items_a = Source(List(10,20,30,40,50))
val items_b = Source(List(60,70,80,90,100))
val sink = ForeachSink[Double](println)
val transform = Flow[Int].map(_ * 2).map(_.toDouble).to(sink)
val materialized = FlowGraph { implicit builder =>
import FlowGraphImplicits._
val merge = Merge[Int]("m1")
items_a ~> merge
items_b ~> merge ~> transform
}.run
在此示例中,您可以看到我使用Flow
随播广告中的帮助程序创建没有特定输入Flow
的{{1}}。然后,我可以将其附加到合并点以进行其他处理。
答案 1 :(得分:4)
使用Source.combine
:
val items_a :: items_b :: items_c = List(
Source(List(10,20,30,40,50)),
Source(List(60,70,80,90,100),
Source(List(110,120,130,140,1500))
Source.combine(items_a, items_b, items_c : _*)(Merge(_))
.map(_+1)
.runForeach(println)
答案 2 :(得分:0)
或者,如果您需要保留输入源的顺序(例如,items_a必须在items_b之前,items_b必须在items_c之前),您可以使用Concat而不是Merge。
val items_a :: items_b :: items_c = List(
Source(List(10,20,30,40,50)),
Source(List(60,70,80,90,100),
Source(List(110,120,130,140,1500))
Source.combine(items_a, items_b, items_c : _*)(Concat(_))