You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ApiFuture类型转换为ZIO的Task类型?

ApiFuture<A>是Google官方提供的异步返回类型,本质为Guava ListenableFuture的子类,可通过以下两种方案转换为ZIO的Task[A]类型适配函数式开发:

方案1:原生异步封装(无需额外依赖)

通过ApiFuture自带的回调接口直接封装为ZIO异步Task,适合不想引入额外依赖的场景:

import com.google.api.core.{ApiFuture, ApiFutureCallback, ApiFutures}
import zio.Task
import java.util.concurrent.Executor

def apiFutureToTask[A](future: => ApiFuture[A])(implicit exec: Executor): Task[A] =
  Task.async { callback =>
    ApiFutures.addCallback(
      future,
      new ApiFutureCallback[A] {
        override def onFailure(t: Throwable): Unit = callback(Left(t))
        override def onSuccess(result: A): Unit = callback(Right(result))
      },
      exec
    )
  }

参数说明:

  • 入参future: => ApiFuture[A]采用惰性求值声明,避免ApiFuture在ZIO调度执行前提前触发,符合纯函数effect的懒执行特性
  • 隐式参数exec可传入项目自定义线程池,也可直接使用ZIO内置线程池:zio.Runtime.defaultExecutor.asJava

方案2:基于ZIO Guava互操作库实现

如果项目允许引入第三方互操作依赖,可使用zio-interop-guava简化实现,依赖坐标(SBT):
"dev.zio" %% "zio-interop-guava" % "31.0.1.0"

转换代码:

import com.google.api.core.ApiFuture
import zio.Task
import zio.interop.guava._

def apiFutureToTask[A](future: => ApiFuture[A]): Task[A] =
  Task.fromListenableFuture(future)

优化使用体验

可以通过隐式扩展方法简化全局调用,无需每次手动包裹转换函数:

implicit class ApiFutureOps[A](private val future: => ApiFuture[A]) extends AnyVal {
  // 对应方案1的扩展方法,若使用方案2可去掉implicit exec参数
  def toTask(implicit exec: Executor): Task[A] = apiFutureToTask(future)
}

// 调用示例:直接对Firebase返回的ApiFuture调用toTask即可
val getUserTask: Task[UserRecord] = FirebaseAuth.getInstance().getUserAsync("target-uid").toTask

注意事项

  • 转换后的Task[A]天然支持ZIO所有内置操作符,可直接使用retry、timeout、race等能力
  • 不要提前求值ApiFuture实例,保证转换过程的纯函数特性,避免副作用提前触发

内容的提问来源于stack exchange,提问作者Nimrod Sadeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:57:01