我有一个简单的方法返回Future[Either[Throwable, MyValue]]
. 现在我想将其转换为ZIO。我创建了:
def zioMethod(): ZIO[Any, Throwable, MyValue] =
ZIO.fromFuture {implicit ec =>
futureEitherMethod().flatMap { result =>
Future(result)
}
}
但它并非无痕无踪:No implicit found for parameter trace: Trace
.
因此,在我添加Trace
为隐式后,它仍然无法正常工作。 还有其他方法可以将Future[Either[,]]
转换为ZIO
吗?本主题中的文档不清楚。
签名(在代码或 scaladoc 中)在这个主题上似乎相当清楚:
ZIO.fromFuture[A]
将Future[A]
转换为ZIO[Any, Throwable, A]
。
你传入一个Future[Either[Throwable, MyValue]]
,所以它会返回一个ZIO[Any, Throwable, Either[Throwable, MyValue]]
- 而不是你的代码所期望的ZIO[Any, Throwable, MyValue]
。
要将Either
的Left
情况转移到ZIO
的"错误通道"上,您有几种选择,例如:
将Future[Either[Throwable, MyValue]]
转换为Future[MyValue]
,然后转换为 ZIO:
def zioMethod(): ZIO[Any, Throwable, MyValue] =
ZIO.fromFuture { implicit ec =>
futureEitherMethod().flatMap {
case Right(myValue) => Future.successful(myValue)
case Left(throwable) => Future.failed(throwable)
}
}
转换为ZIO[Any, Throwable, Either[Throwable, MyValue]]
,然后转换为ZIO[Any, Throwable, MyValue]
:
def zioMethod(): ZIO[Any, Throwable, MyValue] = {
val fromFuture: ZIO[Any, Throwable, Either[Throwable, MyValue]] =
ZIO.fromFuture { implicit ec =>
futureEitherMethod()
}
fromFuture.flatMap(ZIO.fromEither)
}
顺便说一句:对我来说,这在编译时不会在代码中引入任何其他隐式:https://scastie.scala-lang.org/dRefNpH0SEO5aIjegV8RKw
更新:替代(更惯用?)解决方案正如@LMeyer在评论中指出的那样,还有ZIO.absolve
,对我来说,这似乎是更 ZIO 惯用的方式(我自己对 ZIO 的经验几乎为零):
ZIO.fromFuture { implicit ec =>
futureEitherMethod()
}.absolve