简体   繁体   English

scala如何将一种类型的未来转换为另一种类型的未来

[英]scala how to convert future of one type to future of another type

i have a function which retrieve data from DB and return type of Future[ResponseDTO], then I need to convert it to Future of HttpResponse 我有一个从DB检索数据并返回Future [ResponseDTO]类型的函数,然后我需要将它转换为HttpResponse的Future

my code: 我的代码:

val responseDTO = database.getResponseDto(service) => Future[ResponseDTO]

responseDTO.onComplete {
   case Success(responseDTO) => HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload)
   case Failure(exception) => HttpError("error")
}

it wont work 它不会工作

tried this one too, still don't work 尝试了这个,仍然不工作

responseDTO.map(
  dto => EitherT.pure[Future, HttpError](HttpResponse(status = dto.responseCode, entity = dto.responsePayload))
)

Using transform should give the answer you want: 使用transform应该给出你想要的答案:

responseDTO.transform {
  case Success(responseDTO) => Success(HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload))
  case _ => Success(HttpError("error"))
}

This will return a successful Future whose result type is compatible with both HttpResponse and HttpError . 这将返回一个成功的Future其结果类型与HttpResponseHttpError兼容。

If you want to retain the information about success/failure it is best to do this by using the status of the Future . 如果要保留有关成功/失败的信息,最好使用Future的状态来执行此操作。 In that case your code would use an alternate version of transform , like this: 在这种情况下,您的代码将使用替换版本的transform ,如下所示:

case class HttpErrorException(err: HttpError) extends Throwable

responseDTO.transform(
  responseDTO => HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload),
  _ => HttpErrorException(HttpError("error"))
)

You can then use the Future methods in the rest of the code to extract the HttpResponse or HttpErrorException when required. 然后,您可以在其余代码中使用Future方法在需要时提取HttpResponseHttpErrorException

You want to map the future. 你想映射未来。 The .onComplete method doesn't transform the future, just adds an handler (useful for side effects) .onComplete方法不会改变未来,只需添加一个处理程序(对副作用有用)

responseDTO.map(dto => HttpResponse(status=dto.responseCode, entity=dto.responsePayload))

You need to use .map for mapping a successful future computation, use .recover to map an exception during future computation and Either to have a successful/failed result. 您需要使用.map映射成功的未来计算,使用.recover在将来的计算过程中映射异常,并Either成功/失败的结果。

    val responseDTO: Future[ResponseDTO] = ... 

    val future: Future[Either[HttpError, HttpResponse]] = 
      responseDTO
        .map(d => Right(HttpResponse(status = d.responseCode, entity = d.responsePayload)))
        .recover {
          case t: Throwable => Left(HttpError("error"))
        }

if your classes have one superclass, let's say: 如果你的班级有一个超类,那么让我们说:

trait Http

case class HttpResponse(...) extends Http

case class HttpError(...) extends Http

you can avoid using Either : 你可以避免使用Either

    val future: Future[Http] =
      responseDTO
        .map(d => HttpResponse(status = d.responseCode, entity = d.responsePayload))
        .recover {
          case t: Throwable => HttpError("error")
        }

你需要做的是将你以前的A类未来映射到B类的新未来,未来的onComplete方法是副作用,只是有助于将回调附加到结果,其方法签名返回Unit。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM