如何在.mapParallelUnordered中处理错误并使Observable保持活动状态

时间:2019-04-16 14:34:20

标签: scala observable monix

我正在使用Monix 3,并且有这样一种代码:

  Observable.fromIterable(Seq(1, 2, 3, 4, 5, 6, 7, 8, 9))
    .flatMap(i =>
      if (i % 2 == 0) {   // Bad i
        Observable.empty
      } else
        Observable.pure(i)
    )
    .foreachL(i => print(s"Good i: $i"))   /*Output: Good i: 1
                                                     Good i: 3
                                                     Good i: 5
                                                     Good i: 7
                                                     Good i: 9*/

这段代码很好用,但是我有很多长时间的IO操作,因此决定使用.mapParallelUnordered进行重构:

  Observable.fromIterable(Seq(1, 2, 3, 4, 5, 6, 7, 8, 9))
    .mapParallelOrdered(3)(i =>
      if (i % 2 == 0) {
        Task.raiseError(new Exception(s"Bad i: $i"))
      } else
        Task.pure(i)
    )
    .foreachL(i => print(s"Good i: $i"))    /*Output: Good i: 1*/

我试图获得与第一个示例相同的结果,但是是在并行处理中。问题是Task.raiseError杀死了整个可观察到的东西,所以它停止在i = 2上。

如何处理错误并保持Observable存活?

1 个答案:

答案 0 :(得分:3)

您可以尝试以下方法:

Observable
  .fromIterable(Seq(1, 2, 3, 4, 5, 6, 7, 8, 9))
  .mapParallelOrdered(3)(
    i =>
      if (i % 2 == 0) {
        Task.pure(Left("Error"))
      } else
        Task.pure(Right(i))
  )
  .collect {
    case Right(i) => i
  }
  .foreachL(i => print(s"Good i: $i"))