Monix Observable处理错误的更好方法

时间:2019-04-10 13:43:51

标签: scala observable monix

我正在尝试使用monix 3.0.0-RC1构建响应式应用程序。

例如a的Seq为Int,第二个元素是错误的。我可以使用Oservable.raiseError(...)处理此问题:

  Observable.fromIterable(Seq(1,2,3))
    .flatMap( i =>
      if (i == 2) Observable.raiseError(new Exception("Wrong i"))
      else Observable.pure(i)
    )
    .doOnNext(i => println(s"Processing $i"))
    .foreachL(i => println(s"Finished $i"))
    .onErrorHandle(_ => Task.unit)

我不喜欢上面代码中的抛出异常。

另一方面,我可以使用Scala的Either

Observable.fromIterable(Seq(1,2,3))
  .map( i =>
    if (i == 2) Left("Wrong i")
    else Right(i)
  )
  .doOnNext(either => either.map( i => println(s"Processing $i") ))
  .foreachL(either => either.map( i => println(s"Finished $i") ))

但是either => either.map(...)的每一步都不酷。

处理错误的更好方法是什么?

2 个答案:

答案 0 :(得分:3)

例如,如果您只关心正确的结果,则可以使用collect

val logError = {
  case Right(_) => Task.unit
  case Left(i) => Task.delay(println(s"An error occured $i"))
}

Observable.fromIterable(Seq(1,2,3))
  .map( i =>
    if (i == 2) Left("Wrong i")
    else Right(i)
  )
  .doOnNext(logError)
  .collect {
    case Right(value) => value
  }
  .foreachL(i => println(i))

答案 1 :(得分:1)

如果您想drop坏元素,可以用这种方法来做。

Clustered index seek (clustered)

基本上继续使用Task和Observable.fromIterable(1 to 3) .mapEval(p => { if(i == 2) Task.raiseError(new Exception) else Task.now(i) }.attempt ) .collect { case Right(v) => v } .foreachL(println) .runToFuture /* 1 3 */ 将Task组成转换为Task [Either]。