如何将Akka Streams Merge的输出传输到另一个Flow?

时间:2014-12-01 16:43:02

标签: scala stream akka

我正在玩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

3 个答案:

答案 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(_))