3

我创建了两个版本的服务。第一个使用Futures,另一个ZIO用作效果。

我有一个简单的方法,它使用Future结果效果:

def get(id: String)(implicit executionContext: ExecutionContext): Future[Data]

我还有一些其他版本使用ZIO[SomeEnv, SomeError, Data]

def get(id: String): ZIO[SomeEnv, SomeError, Data]

现在,我需要创建某种适配器,它将从一个版本或另一个版本返回数据:

def returnDataFromServiceVersion(version: Int) : ??? = {
   if(version == 1) futureService.get(...)
   else zioService.get(...)
}

这里的问题是返回类型。我不知道如何转换ZIO为未来或Future转换ZIO为具有共同的返回类型。我尝试使用ZIO.fromFuture{...}ortoFuture()但它没有帮助。我的问题是 - 如何创建此returnDataFromServiceVersion方法以将其与两种服务一起使用?我需要在这里有共同的返回类型。

或者也许有另一种方法来解决这个问题?

4

2 回答 2

5

您必须决定您的函数是否返回Future,或者ZIO这不能依赖于version代码片段中的运行时值(当然,除非您将返回类型定义为AnyRef- 不是很有用)。
如果您的程序的其余部分基于Futures,但您想开始ZIO在某些服务中引入,您可以通过自己执行效果来做到这一点runtime.unsafeRun(effect)

val runtime = Runtime.default

def returnDataFromServiceVersion(version: Int): Future[Data] = {
  runtime.unsafeRunToFuture(
    zioService.get(...)
  )
}

有关更多详细信息,请参阅官方 ZIO 文档中的运行效果

于 2020-07-01T14:26:36.447 回答
2

如果我理解正确你想要的是ZIO看起来像这样的常见类型ZIO[SomeEnv, SomeError, Data]

这可以使用ZIO.fromFuture和映射Throwable(这是Future失败类型)到您的SomeError

  case class Data(data: String)
  case class SomeEnv(env: String)
  case class SomeError(err: String)

  object SomeError {
    def fromThrowable(throwable: Throwable) = SomeError(throwable.toString)
  }

  def getFuture(id: String)(implicit executionContext: ExecutionContext): Future[Data] = ???
  def getZIO(id: String): ZIO[SomeEnv, SomeError, Data] = ???

  def returnDataFromServiceVersion(version: Int): ZIO[SomeEnv, SomeError, Data] =
    if (version == 1)
      ZIO
        .fromFuture(executionContext => getFuture("id")(executionContext))
        .mapError(SomeError.fromThrowable)
    else
      getZIO("id")
于 2020-07-01T14:22:27.390 回答