组成必需和可选值的期货
Composing Futures of a required and optional value
假设我正在编写一个接收 Future[A]
和 Future[B]
以及 returns Future[(A, Option[B])]
的函数,如下所示:
// return the result of "fa" and then
// either "Some" of the result of "fb" if "fb" has been completed successfully
// or None if "fb" is still not completed or failed
// Note: we check `fb` result after `fa` has completed.
def foo(fa: Future[A], fb: Future[B]): Future[(A, Option[B])] = ???
// foo(Future.successful(a), Future.successful(b)) // Future.successful(a, Some(b))
// foo(Future.successful(a), Future.failed(...)) // Future.successful(a, None)
// foo(Future.successful(a), Future.never) // Future.successful(a, None)
// foo(Future.failed(...), Future.successful(b)) // Future.failed(...)
// foo(Future.failed(...), Future.never) // Future.failed(...)
我这样写foo
:
def foo(fa: Future[A], fb: Future[B]): Future[(A, Option[B])] = for {
a <- fa
ob <- if (fb.isCompleted) fb.recover { case NonFatal(_) => None } else Future.successful(None)
} yield (a, ob)
这个实现似乎有效。你会如何纠正或改进它?
您可以使用 value
轻松定义 foo
def foo(fa: Future[A], fb: Future[B])(implicit ec: ExecutionContext): Future[(A, Option[B])] =
fa.map(a => a -> fb.value.flatMap(_.toOption))
这非常有效,因为 value
完全代表您想要的,即 Future 的值(如果它完成)或 None
;此外,由于该值还捕获了作为 Try 失败的可能性,而您想要的只是将其转换为 Option ,您有一个漂亮的 -班轮.
一如既往,Scaladoc 是你的朋友 ;)
假设我正在编写一个接收 Future[A]
和 Future[B]
以及 returns Future[(A, Option[B])]
的函数,如下所示:
// return the result of "fa" and then
// either "Some" of the result of "fb" if "fb" has been completed successfully
// or None if "fb" is still not completed or failed
// Note: we check `fb` result after `fa` has completed.
def foo(fa: Future[A], fb: Future[B]): Future[(A, Option[B])] = ???
// foo(Future.successful(a), Future.successful(b)) // Future.successful(a, Some(b))
// foo(Future.successful(a), Future.failed(...)) // Future.successful(a, None)
// foo(Future.successful(a), Future.never) // Future.successful(a, None)
// foo(Future.failed(...), Future.successful(b)) // Future.failed(...)
// foo(Future.failed(...), Future.never) // Future.failed(...)
我这样写foo
:
def foo(fa: Future[A], fb: Future[B]): Future[(A, Option[B])] = for {
a <- fa
ob <- if (fb.isCompleted) fb.recover { case NonFatal(_) => None } else Future.successful(None)
} yield (a, ob)
这个实现似乎有效。你会如何纠正或改进它?
您可以使用 value
foo
def foo(fa: Future[A], fb: Future[B])(implicit ec: ExecutionContext): Future[(A, Option[B])] =
fa.map(a => a -> fb.value.flatMap(_.toOption))
这非常有效,因为 value
完全代表您想要的,即 Future 的值(如果它完成)或 None
;此外,由于该值还捕获了作为 Try 失败的可能性,而您想要的只是将其转换为 Option ,您有一个漂亮的 -班轮.
一如既往,Scaladoc 是你的朋友 ;)