【发布时间】:2016-02-25 19:21:21
【问题描述】:
有没有办法转换一个
Either[A, Future[B]]
到一个
Future[Either[A, B]]
我想到了类似Future.sequence 方法,它从List[Future] 转换为Future[List]
【问题讨论】:
有没有办法转换一个
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
【讨论】:
sequence 类型签名很有帮助(至少它可以帮助我弄清楚哪个高阶函数可以在我的 Scala 代码中工作):sequence :: (Monad m, Traversable t) => t (m a) -> m (t a)。
Dumonad 增加了一组扩展方法来简化响应式编程:
import io.github.dumonad.dumonad.Implicits._
val eitherOfFuture: Either[L,Future[R]]
val futureOfEither: Future[Either[L,R]] = eitherOfFuture.extractFuture
【讨论】: