Akka流使流动变平

时间:2017-09-10 12:59:06

标签: scala akka-stream

流量可以与"2" + "5" == "25"连接,如:

via

我想做相当于def aToB: Flow[A, B, NotUsed] = { ??? } def bToC: Flow[B, C, NotUsed] = { ??? } def aToC: Flow[A, C, NotUsed] = { aToB.via(bToC) }

flatMap

是否有一些内置的方法def aToSomeB: Flow[A, Some[B], NotUsed] = { ??? } def aToSomeC: Flow[A, Some[C], NotUsed] = { aToSomeB.flatVia(bToC) } ?这似乎是flatVia解缠和错误展平等常见需求。

1 个答案:

答案 0 :(得分:2)

这取决于你是否有兴趣保留这些None,或者你想把它们扔掉。

当您输入Flow[A, Some[C], NotUsed]时,您似乎根本不对None感兴趣。这意味着您可以使用collect轻松过滤掉它们,例如

def aToSomeC: Flow[A, C, NotUsed] = { aToSomeB.collect{case Some(x) ⇒ x}.via(bToC) }

如果您需要跟踪None s(或Left s,如果您正在处理Either s),则需要写下“提升” “上演自己。这可以写得相当普遍。例如,它可以写为一个函数,它接受任何流Flow[I, O, M]并返回另一个流Flow[Either[E, I], Either[E, O], M]。因为它需要扇出和扇入阶段,所以需要使用GraphDSL。

  def liftEither[I, O, E, M](f: Flow[I, O, M]): Graph[FlowShape[Either[E, I], Either[E, O]], M] =
    Flow.fromGraph(GraphDSL.create(f) { implicit builder: GraphDSL.Builder[M] => f =>

      val fIn      = builder.add(Flow[Either[E, I]])
      val p        = builder.add(Partition[Either[E, I]](2, _.fold(_ ⇒ 0, _ ⇒ 1)))
      val merge    = builder.add(Merge[Either[E, O]](2))
      val toRight  = builder.add(Flow[O].map(Right(_)))

                 p.out(0).collect{case Left(x) ⇒ Left(x)}             ~> merge
      fIn.out ~> p.in
                 p.out(1).collect{case(Right(x)) ⇒ x} ~> f ~> toRight ~> merge

      new FlowShape(fIn.in, merge.out)
    })

这可以按照以下方式使用

  def aToSomeB: Flow[A, Either[Throwable, B], NotUsed] = ???
  def aToSomeC: Flow[A, Either[Throwable, C], NotUsed] = aToSomeB.via(liftEither(bToC))

请注意,Option可以很容易地转换为Either以利用相同的帮助函数。