Scala Akka溪流通过
流可以通过以下方式与Scala Akka溪流通过,scala,akka-stream,Scala,Akka Stream,流可以通过以下方式与连接: 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
连接:
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
?这似乎是一种常见的需求,比如选项
展开和错误平坦化。这取决于您是否有兴趣保留那些无
选项,或者是否想将它们扔掉
当您将流输入为flow[A,Some[C],NotUsed]
is时,您似乎对None
s一点也不感兴趣。这意味着您可以使用collect
轻松过滤掉它们,例如:
def aToSomeC: Flow[A, C, NotUsed] = { aToSomeB.collect{case Some(x) ⇒ x}.via(bToC) }
否则,如果您需要跟踪None
s(或Left
s,如果您正在处理或s),您需要自己编写“提升”阶段。这可以写得相当笼统。例如,它可以写成一个函数,它接受任何流flow[I,O,M]
,并返回另一个流flow[E,I],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))
请注意,选项
s可以很容易地转换为或
s,以利用相同的助手功能。谢谢。我有点惊讶,这里面没有内置的东西;平坦化一系列的Eithers或Optionals不是一个共同的需求吗?我同意这是一个共同的需求,特别是如果你想让你的流阶段“参考透明”的话。然而,akka stream在某种程度上是一个较低级别的工具包,它的应用程序太多,因此很难清楚地定义哪些应该是它的一部分,哪些不应该。。