如何在Scala中从Future [Ething [Left,Right]]中获得Future [Right]?

问题描述

我有两种已经存在的方法

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之前,您无法确定外部LeftRight还是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]

,

作为其他答案的补充,如果您使用的是猫,并且ErrorThrowable的子类,则可以只使用rethrow

import cats.implicits._


val result: Future[Value] = resultFromB.rethrow