假设我有一个函数 foo
执行异步计算并返回 Future
:
def foo(x: Int)(implicit ec: ExecutionContext): Future[Int] = ???
现在我想重试这个计算 n
直到计算成功为止。
def retryFoo(x: Int, n: Int)(implicit ec: ExecutionContext): Future[Int] = ???
我还想返回重试时抛出的所有个异常。所以,我定义了新的异常类 ExceptionsList
并要求 retryFoo
返回 ExceptionsList
当所有重试都失败时。
case class ExceptionsList(es: List[Exception]) extends Exception { ... }
你会怎么写retryFoo
重试foo
并返回 Future
使用 foo
结果或ExceptionsList
?
最佳答案
我可能会这样做:
final case class ExceptionsList(es: List[Throwable]) extends Throwable
def retry[T](n: Int, expr: => Future[T], exs: List[Throwable] = Nil)(implicit ec: ExecutionContext): Future[T] =
Future.unit.flatMap(_ => expr).recoverWith {
case e if n > 0 => retry(n - 1, expr, e :: exs)
case e => Future.failed(new ExceptionsList(e :: exs))
}
expr
是按名称调用的,因为它本身可以抛出异常而不是返回失败的 Future。我将累积的异常记录在一个列表中,但我想这是一种品味。
关于scala - 重试返回 Future 的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59032680/