是否有任何理由使 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。有Option
、Either
、Try
和Future
。 (Future
的要点是抽象异步操作,错误处理是为了方便起见)。 Scalaz 甚至更多:Validation
(Disjunction
和 Maybe
优于 Either
和 Option
)。
它们对错误值的处理都有点不同。然而 Try
和 Future
非常相似,都换行 Throwable
。所以 恕我直言,Future[Try[A]]
没有添加太多信息(关于错误)。与 Future[Future[A]]
或 Try[Try[A]]
相比。 OTOH Future[Option[A]]
或 Future[Either[MyError, A]]
对我来说很有意义。
可能存在一些情况,例如 f: A => B
和 g: 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)
在这种情况下,我宁愿重构 f
和 g
以获得 更好的 类型,至少:f: A => Option[B]
和 g: B => Option[C]
然后,以 Future[Option[C]]
.
结尾
Try[A]
表示可能会失败的同步 计算。
Future[A]
表示可能会失败的 异步 计算。
根据此定义,Future[Try[A]]
表示在异步计算(可能失败)内部执行的同步计算(可能失败)的结果。
有意义吗?对我来说不是,但我愿意接受创造性的解释。
考虑到 Future
结果上的任何模式匹配都匹配 Success[A]
和 Failure[A]
(onComplete()
、andThen()
)(因为他们期望 Try[A]
作为参数,直接或通过部分函数),是否存在我想明确说明函数类型为 Future[Try[A]]
的情况?
Scala 中有各种结构,其中包含 failure case。有Option
、Either
、Try
和Future
。 (Future
的要点是抽象异步操作,错误处理是为了方便起见)。 Scalaz 甚至更多:Validation
(Disjunction
和 Maybe
优于 Either
和 Option
)。
它们对错误值的处理都有点不同。然而 Try
和 Future
非常相似,都换行 Throwable
。所以 恕我直言,Future[Try[A]]
没有添加太多信息(关于错误)。与 Future[Future[A]]
或 Try[Try[A]]
相比。 OTOH Future[Option[A]]
或 Future[Either[MyError, A]]
对我来说很有意义。
可能存在一些情况,例如 f: A => B
和 g: 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)
在这种情况下,我宁愿重构 f
和 g
以获得 更好的 类型,至少:f: A => Option[B]
和 g: B => Option[C]
然后,以 Future[Option[C]]
.
Try[A]
表示可能会失败的同步 计算。
Future[A]
表示可能会失败的 异步 计算。
根据此定义,Future[Try[A]]
表示在异步计算(可能失败)内部执行的同步计算(可能失败)的结果。
有意义吗?对我来说不是,但我愿意接受创造性的解释。