j3d*_*j3d 2 scala future for-comprehension
给出以下List整数......
val l = List(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
...我需要调用2个方法来返回Future每个元素并获得以下结果:
Future(Some(1), Some(2), Some(3))
Run Code Online (Sandbox Code Playgroud)
以下是我的尝试:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def f1(i: Int) = Future(i)
def f2(i: Int) = Future { if (i % 2 == 0) throw new Exception else i }
val l = List(1, 2, 3)
val results = Future.sequence(l.map { i =
val f = for {
r1 <- f1(i)
r2 <- f2(i) // this throws an exception if i is even
} yield Some(r1)
f.recoverWith {
case e => None
}
})
Run Code Online (Sandbox Code Playgroud)
如果f2失败,我想恢复并继续使用剩余的元素.上面的代码不起作用,因为recoverWith永远不会调用,即使f2失败.
如何在f2失败时恢复,以便最终结果是这样的?
Future(Some(1), None, Some(3))
Run Code Online (Sandbox Code Playgroud)
第二个元素应该是None因为f2当输入整数是偶数(即2)时失败.
当recoverWith输出类型为Future,它工作正常.
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def f1(i: Int) = Future(i)
def f2(i: Int) = Future { if (i % 2 == 0) throw new Exception else i }
val l = List(1, 2, 3)
val results = Future.sequence(l.map { i =>
val f = for {
r1 <- f1(i)
r2 <- f2(i) // this might throw an exception
} yield Some(r1)
f.recoverWith {
case e => Future { println("Called recover " + i); None } // wrapped in Future
}
})
results onComplete println
Run Code Online (Sandbox Code Playgroud)
结果:
// Called recover 2
// Success(List(Some(1), None, Some(3))
// tried with scala version: 2.10.4
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3246 次 |
| 最近记录: |