问题描述
我有方法
<ng-container [ngSwitch]="someCondition">
<ng-template *ngSwitchCase="'first'">
<div class="row">
first
</div>
</ng-template>
<ng-template *ngSwitchCase="'second'">
<div class="row">
second
</div>
</ng-template>
<ng-template *ngSwitchCase="'third'">
<div class="row">
third
</div>
</ng-template>
</ng-container>
我还有另一个功能
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]
无法使用,因为map对类型不满意。
解决方法
您尝试做的基本上是类似
def convert[A](future: Future[Either[CustomException,A]]): Option[A] =
Try(Await.result(future,timeout)).toEither.flatten.toOption
此:
- 丢失有关错误的信息,从而阻止调试(尽管您可以在
.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[Either[CustomException,A]]
可能只是以这种方式下注,或以IO[Either[CustomException,A]]
形式放入IO。如果您不关心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
但所有等待警告均适用。参见the documentaion,转载于此:
警告:强烈建议不要提供冗长的超时,因为调用线程的进程将被挂起(阻塞),直到“等待”结果或超时到期为止。