Either[A, Future[B]] 到 Future[Either[A, B]]

Either[A, Future[B]] to Future[Either[A, B]]

有没有办法转换成

Either[A, Future[B]] 

Future[Either[A, B]]

我想到了类似 Future.sequence 的方法,它从 List[Future] 转换为 Future[List]

不确定是否有开箱即用的解决方案,这是我想出的:

def foldEitherOfFuture[A, B](e: Either[A, Future[B]]): Future[Either[A, B]] =
  e match {
    case Left(s) => Future.successful(Left(s))
    case Right(f) => f.map(Right(_))
  }

除了捕获来自 Future 的最终异常之外,您还可以添加 recover 并将其映射到 Left:

case Right(f) => f.map(Right(_)).recover { case _ => Left(/** some error*/) }

没有 api 函数调用可以做到这一点。我会尝试这样的事情:

def getResult[A, B]: Either[A, Future[B]] = ???
val res = getResult.fold(fa = l => Future(Left(l)), fb = r => r.map(value => Right(value)))

如果您使用的是 scalaz,则只需使用 sequenceU

import scala.concurrent.ExecutionContext.Implicits.global
import scalaz._
import Scalaz._

val x: Either[String, Future[Int]] = ???
val y: Future[Either[String, Int]] = x.sequenceU

更新(2019 年 8 月):

如果您使用的是猫,请使用 sequence:

import cats.implicits._
import scala.concurrent.ExecutionContext.Implicits.global

val x: Either[String, Future[Int]] = ???
val y: Future[Either[String, Int]] = x.sequence

Dumonad 添加一组扩展方法以简化响应式编程:

import io.github.dumonad.dumonad.Implicits._

val eitherOfFuture: Either[L,Future[R]]

val futureOfEither: Future[Either[L,R]] = eitherOfFuture.extractFuture