更新时间:2023-11-23 15:52:04
真正有用的事情(一般来说)是能够将未来的错误转化为正确的价值.或者换句话说,将一个 Future[T]
转换成一个 Future[Try[T]]
(成功的返回值变成了一个 Success[T]
code> 而失败案例变成了 Failure[T]
).下面是我们如何实现它:
A genuinely useful thing (generally speaking) would be to be able to promote the error of a future into a proper value. Or in other words, transform a Future[T]
into a Future[Try[T]]
(the succesful return value becomes a Success[T]
while the failure case becomes a Failure[T]
). Here is how we might implement it:
// Can also be done more concisely (but less efficiently) as:
// f.map(Success(_)).recover{ case t: Throwable => Failure( t ) }
// NOTE: you might also want to move this into an enrichment class
def mapValue[T]( f: Future[T] ): Future[Try[T]] = {
val prom = Promise[Try[T]]()
f onComplete prom.success
prom.future
}
现在,如果您执行以下操作:
Now, if you do the following:
Future.traverse(seq)( f andThen mapValue )
您将获得一个成功的 Future[Seq[Try[A]]]
,其最终值包含每个成功未来的 Success
实例,以及一个 Failure
每个失败的未来实例.如果需要,您可以在此序列上使用 collect
删除 Failure
实例并仅保留成功的值.
You'll obtain a succesful Future[Seq[Try[A]]]
, whose eventual value contains a Success
instance for each successful future, and a Failure
instance for each failed future.
If needed, you can then use collect
on this seq to drop the Failure
instances and keep only the sucessful values.
换句话说,您可以按如下方式重写您的辅助方法:
In other words, you can rewrite your helper method as follows:
def traverseFilteringErrors[A, B](seq: Seq[A])(f: A => Future[B]): Future[Seq[B]] = {
Future.traverse( seq )( f andThen mapValue ) map ( _ collect{ case Success( x ) => x } )
}