Scala Akka流:如何等待多个流完成

Scala Akka流:如何等待多个流完成,scala,akka,akka-stream,Scala,Akka,Akka Stream,我的程序中有几个Flows,我想并行处理。在一切都完成之后,我想触发一些行动 一种方法是在每次完成后向参与者发送一条消息,当参与者验证所有流都已就绪时,它可以触发该操作 我想知道在akka streams Scala DSL中是否有我可能忽略的东西可以让它变得更简单 编辑: 将流转换为未来将不起作用,因为正如文档所提到的,未来将在流中发生的第一个事件之后立即完成。运行以下代码: implicit val system = ActorSystem("Sys") val fm = FlowMater

我的程序中有几个
Flow
s,我想并行处理。在一切都完成之后,我想触发一些行动

一种方法是在每次完成后向参与者发送一条消息,当参与者验证所有流都已就绪时,它可以触发该操作

我想知道在akka streams Scala DSL中是否有我可能忽略的东西可以让它变得更简单

编辑: 将流转换为未来将不起作用,因为正如文档所提到的,未来将在流中发生的第一个事件之后立即完成。运行以下代码:

implicit val system = ActorSystem("Sys")
val fm = FlowMaterializer(MaterializerSettings())

def main(args: Array[String]): Unit = {
  val fut = Flow(1 second, {() => println("tick")}).toFuture(fm)

  fut.onComplete{ _ =>
    println("future completed")
  }
}

打印“tick”,然后是“future completed”,然后是无限的“tick”序列。

如评论中所述,我相信@Eduardo将
转换为
未来
是正确的。考虑这个例子:

implicit val system = ActorSystem("Sys")
import system.dispatcher

val text1 = 
  """hello1world
  foobar""".stripMargin

val text2 = 
  """this1is
  a1test""".stripMargin

def flowFut(text:String) = Flow(text.split("\\s").toVector)
  .map(_.toUpperCase())
  .map(_.replace("1", ""))
  .toFuture(FlowMaterializer(MaterializerSettings()))    


val fut1 = flowFut(text1)    
val fut2 = flowFut(text2)    
val fut3 = for{
  f1 <- fut1
  f2 <- fut2
} yield {
  s"$f1, $f2"
}

fut3 foreach {println(_)}
implicit val system=ActorSystem(“Sys”)
导入system.dispatcher
val text1=
“你好
foobar“.”带边框
val text2=
“这是
a1test“.”条边距
def flowFut(text:String)=流(text.split(\\s”).toVector)
.map(u.toUpperCase())
.map(u.replace(“1”和“))
.toFuture(FlowMaterializer(MaterializerSettings()))
val fut1=流量FUT(文本1)
val fut2=流量FUT(文本2)
val fut3=用于{

哦,我明白了。如果流程处理多个元素,那么未来将在第一个元素之后完成

我认为你可以使用flow.onComplete来完成一些承诺

val promise1 = Promise[Unit]()
val promise2 = Promise[Unit]()

val flow1 = Flow(Iterator(1,2,3,4)).map(println)
val flow2 = Flow(Iterator('a,'b,'c,'d)).map(println)


flow1.onComplete(FlowMaterializer(MaterializerSettings())){
  case Success(_) =>  promise1.success()
  case Failure(e) => promise1.failure(e)
}
flow2.onComplete(FlowMaterializer(MaterializerSettings())){
  case Success(_) =>  promise2.success()
  case Failure(e) => promise2.failure(e)
}

for {
  e1<- promise1.future
  e2<- promise2.future
}{
  println(s"completed!")
}
val promise1=承诺[单位]()
val promise2=承诺[单位]()
val flow1=流(迭代器(1,2,3,4)).map(println)
val flow2=Flow(迭代器('a,'b,'c,'d)).map(println)
flow1.onComplete(FlowMaterializer(MaterializerSettings())){
案例成功()=>承诺1.成功()
案例失败(e)=>承诺1.失败(e)
}
flow2.onComplete(FlowMaterializer(MaterializerSettings())){
案例成功()=>承诺2.成功()
案例失败(e)=>承诺2.失败(e)
}
为了{

e1难道你不能用“问”模式来获取这些流的未来,然后将它们全部投入到一个理解中,从而触发收益率中的动作吗?@TimGautier我认为这些流背后的参与者没有暴露给我,让我能够向他们提出任何要求。此外,我正在寻找完全在流DSL中的东西。根据t流API看起来你可以将流转换成未来,那么应该很容易映射到一个未来:Flow.toFuture(…)。@Julio:是的,但是文档说只要流中有任何操作(而不是流完成时),未来就完成了@Eduardo,我实际上认为Julio是正确的。
Flow
上的每个转换都会产生另一个
Flow
。如果您执行几个转换,然后使用最后一个
Flow
实例调用
toFuture
,那么只有在前面的所有转换都完成后才能满足
Future
d、 流(fromIterable)似乎不再存在