将Either[A, Future[B]]转换为Future[Either[A, B]]。

6
有没有一种方法可以将一个
Either[A, Future[B]] 

转化为

Future[Either[A, B]]

我想到的是类似于Future.sequence方法,它可以将List[Future]转换为Future[List]

4个回答

9

我不确定是否有现成的解决方案,这是我想出来的:

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*/) }

3

目前没有可用的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)))

3
如果您正在使用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月):

如果您正在使用cats,请使用sequence

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

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

我认为查看Haskell的sequence类型签名很有帮助(至少对我来说,它有助于我弄清楚哪个高阶函数适用于我的Scala代码):sequence :: (Monad m, Traversable t) => t (m a) -> m (t a) - Kevin Meredith
我真的希望这个功能能在2.14版的Scala核心中添加。 - Cory Klein

1

Dumonad 添加了一组扩展方法,以便更轻松地进行响应式编程:

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接