问题描述
def methodB(): Future[Either[Error,Value]]
def methodC(futureValue: Future[Value]): Future[Value]
我需要一种方法,该方法将从methodB
中获取结果,并将权利值输入到methodC
中,但是应该是Future:
def methodA(): Future[Either[Error,Value]] = {
val resultFromB: Future[Either[Error,Value]] = methodB()
// get Future[Value] from resultFromB and put it to methodC
resultFromB
}
能请你帮忙吗?也许如何将Future[Either[Error,Value]]
转换为Either[Future[Error],Future[Value]]
?
解决方法
从Future[Value]
获取Future[Either[Error,Value]]
很简单,尽管您需要一个默认值,以防它是Left
而不是Right
:
val default: Value = ???
val res: Future[Value] = resultFromB.map(_.getOrElse(default))
将Future[Either[Error,Value]]
转换为Either[Future[Error],Future[Value]]
是没有意义的,因为在原始Either
之前,您无法确定外部Left
是Right
还是Future
是完整的,在这种情况下,使内部值Future
s没有意义。
由于Future
可能失败,因此您可以这样写:
def fright[A,B](fab: Future[Either[A,B]]): Future[B] =
fab.flatMap(ab => ab.fold(b => Future.failed(new Throwable("t'was left")),b => Future(b)))
,
由于Future
的失败和成功案例与Either
的Left和Right相对应,因此您可以简单地使用-
methodB() flatMap {
case Left(ex) => Future.failed(ex)
case Right(v) => Future.successful(v)
}
这将返回您Future[Value]
作为其他答案的补充,如果您使用的是猫,并且Error
是Throwable
的子类,则可以只使用rethrow
:
import cats.implicits._
val result: Future[Value] = resultFromB.rethrow