![](/img/trans.png)
[英]Convert EitherT[Future, A, Future[B]] to EitherT[Future, A, B]
[英]Convert EitherT[Future, A, B] to Option[B]
我有一个方法
def getInfoFromService(reqParams: Map[String, String]): Future[Either[CustomException, A]]
我还有另一个功能
import cats.implicits._
def processInfoAndModelResponse(input: Future[Either[CustomException, A]]): Option[A] = {
for {
either <- input
resultA <- either
} yield resultA.some
}
所以基本上,我试图将Future[Either[CustomException, A]])
为Option[A]
。 resultA <- either
在上面的代码中都不起作用,因为地图对类型不满意。
你尝试做的基本上是这样的
def convert[A](future: Future[Either[CustomException, A]]): Option[A] =
Try(Await.result(future, timeout)).toEither.flatten.toOption
这个:
.flatten
之后.flatten
)Future
任何好处 Monad 不会那样工作。 基本上,您可以使用for
为同一个 monad 处理多个 monadic 计算,但是Future
和Either
是不同的 monad。
尝试
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
def processInfoAndModelResponse(input: Future[Either[CustomException, A]]): Option[A] = {
Await.result(input, 1.minute).toOption
}
@MateuszKubuszok的答案不同,因为它不会抛出。
您不能明智地将Future[Either[CustomException, A]]
为Option[A]
,因为在 Future 完成之前您不知道结果会是什么。
Future[Either[CustomException, A]]
可能只是打赌保持这种方式,或者将 IO 作为IO[Either[CustomException, A]]
。 如果您不关心CustomException
,您也可以捕获它Future
(或IO
)错误处理机制,或者完全丢弃它。
一些选项:
在 Future 的错误处理中吸收 CustomException:
val fa: Future[A] = fut.transform(_.map(_.toTry))
忽略 CustomException 并使 Future 返回 None
val fa: Future[Option[A]] = fut.map(_.toOption)
如果你真的想阻塞一个线程并等待结果,
Await.result(input, Duration.Inf).toOption
但所有等待的警告都适用。 请参阅此处复制的文档:
警告:强烈建议不要提供过长的超时,因为调用线程的进程将被挂起——阻塞——直到 Awaitable 有结果或超时到期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.