是否有任何理由使 API 类型为 Future[Try[A]] 而不是 Future[A]?

Is there any reason to make API of type Future[Try[A]] instead of Future[A]?

考虑到 Future 结果上的任何模式匹配都匹配 Success[A]Failure[A]onComplete()andThen())(因为他们期望 Try[A] 作为参数,直接或通过部分函数),是否存在我想明确说明函数类型为 Future[Try[A]] 的情况?

Scala 中有各种结构,其中包含 failure case。有OptionEitherTryFuture。 (Future的要点是抽象异步操作,错误处理是为了方便起见)。 Scalaz 甚至更多:ValidationDisjunctionMaybe 优于 EitherOption)。

它们对错误值的处理都有点不同。然而 TryFuture 非常相似,都换行 Throwable。所以 恕我直言Future[Try[A]] 没有添加太多信息(关于错误)。与 Future[Future[A]]Try[Try[A]] 相比。 OTOH Future[Option[A]]Future[Either[MyError, A]] 对我来说很有意义。


可能存在一些情况,例如 f: A => Bg: B => C 可能会失败,并且您希望避免在 ExecutionContext 中创建太多任务:

val a: Future[A] = ???
val c: Future[C] = a.map(f).map(g) // two tasks, not good
val c2: Future[Try[C]] = a.map(x => Try { f(x) } map g ) // one task, maybe better

// get will throw, but exception will be catched by Future's map
// Almost no information is lost compared to `c2`
// You cannot anymore distinguish between possible error in `a`
// and exceptions thrown by `f` or `g`.
val c3: Future[C] = a.map(x => Try { f (x) }.map(g).get)

在这种情况下,我宁愿重构 fg 以获得 更好的 类型,至少:f: A => Option[B]g: B => Option[C] 然后,以 Future[Option[C]].

结尾

Try[A] 表示可能会失败的同步 计算。

Future[A] 表示可能会失败的 异步 计算。

根据此定义,Future[Try[A]] 表示在异步计算(可能失败)内部执行的同步计算(可能失败)的结果。

有意义吗?对我来说不是,但我愿意接受创造性的解释。