使用 Monix Observable 处理错误的更好方法
Better way to handle errors with Monix Observable
我正在尝试使用 monix 3.0.0-RC1 构建响应式应用程序。
比如a有一个Int的Seq,第二个元素是错误的。我可以使用 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(...)
每一步都不酷
处理错误的更好方法是什么?
如果你只关心正确的结果,你可以使用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))
如果你想drop坏元素,你可以这样做。
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,attempt
把Task组合变成Task[Either]。
我正在尝试使用 monix 3.0.0-RC1 构建响应式应用程序。
比如a有一个Int的Seq,第二个元素是错误的。我可以使用 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(...)
每一步都不酷
处理错误的更好方法是什么?
如果你只关心正确的结果,你可以使用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))
如果你想drop坏元素,你可以这样做。
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,attempt
把Task组合变成Task[Either]。