流量可以与"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
解缠和错误展平等常见需求。
答案 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
以利用相同的帮助函数。