将EitherT [Future,A,B]转换为Option [B]

问题描述

我有方法

<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计算,但是FutureEither是不同的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,转载于此:

警告:强烈建议不要提供冗长的超时,因为调用线程的进程将被挂起(阻塞),直到“等待”结果或超时到期为止。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...