[英]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.