Akka Streams(Scala):过滤异常

Akka Streams(Scala):过滤异常,scala,akka-stream,flatmap,Scala,Akka Stream,Flatmap,akka streams管道中的一个步骤是转换,当它接收到无效输入时抛出异常。我想放弃这些有问题的输入。因此,我提出了以下解决方案: ... .map( input => Try( transformation( input ) ).toOption ) .filter( _.nonEmpty ) .map( _.get ) ... 这需要三个步骤,事实上,这只是一个平面图 有没有一种更直接的akka方法可以做到这一点?你可以使用监督策略。摘自文件: val decider: Super

akka streams管道中的一个步骤是转换,当它接收到无效输入时抛出异常。我想放弃这些有问题的输入。因此,我提出了以下解决方案:

...
.map( input => Try( transformation( input ) ).toOption )
.filter( _.nonEmpty )
.map( _.get )
...
这需要三个步骤,事实上,这只是一个平面图


有没有一种更直接的akka方法可以做到这一点?

你可以使用监督策略。摘自文件:

val decider: Supervision.Decider = {
  case _: ArithmeticException => Supervision.Resume
  case _                      => Supervision.Stop
}

val flow = Flow[Int]
  .filter(100 / _ < 50)
  .map(elem => 100 / (5 - elem))
  .withAttributes(ActorAttributes.supervisionStrategy(decider))

查看一下

,如果您想按照示例代码中的指示默默地放弃异常,下面有几种方法可以减少步骤:

// A dummy transformation
def transformation(i: Int): Int = 100 / i

// #1: Use `collect`
Source(List(5, 2, 0, 1)).
  map(input => Try(transformation(input)).toOption).
  collect{ case x if x.nonEmpty => x.get }.
  runForeach(println)
  // Result: 20, 50, 100

// #2: Use `mapConcat`
Source(List(5, 2, 0, 1)).
  mapConcat(input => List(Try(transformation(input)).toOption).flatten).
  runForeach(println)
  // Result: 20, 50, 100
请注意,Akka源/流没有
flatMap
,尽管(和
flatMapConcat
)的工作方式有点类似

// A dummy transformation
def transformation(i: Int): Int = 100 / i

// #1: Use `collect`
Source(List(5, 2, 0, 1)).
  map(input => Try(transformation(input)).toOption).
  collect{ case x if x.nonEmpty => x.get }.
  runForeach(println)
  // Result: 20, 50, 100

// #2: Use `mapConcat`
Source(List(5, 2, 0, 1)).
  mapConcat(input => List(Try(transformation(input)).toOption).flatten).
  runForeach(println)
  // Result: 20, 50, 100