首页 > 解决方案 > 如何将 ApiFuture 转换为 ZIO 任务?

问题描述

我正在使用 Firebase,所以我有很多 type 的返回类型ApiFuture<A>。我想把它们变成一个Task[A]与 ZIO 效果一起工作的东西。

标签: firebasescalazio

解决方案


我们可以创建一个方法来使用 Typeclasses 转换所有这些:

trait EffectUtils[F[_]] {
  def toEffect[A](a: F[A]): Task[A]
}

object EffectUtils {

  implicit val apiFuture: EffectUtils[ApiFuture] = new EffectUtils[ApiFuture] {
    override def toEffect[A](a: ApiFuture[A]): Task[A] = Task.effectAsync[A]( cb =>
      ApiFutures.addCallback(a, new ApiFutureCallback[A] {
        override def onFailure(t: Throwable): Unit = cb(Task.fail(t))
        override def onSuccess(result: A): Unit = cb(Task.succeed(result))
      })
    )
  }

  implicit class ApiFutureOps[A](f: ApiFuture[A]) {
    def toEffect(implicit instance: EffectUtils[ApiFuture]) = instance.toEffect(f)
  }
}

现在,当我们发出 API 请求并希望将结果转换为 ZIO 类型时,这很容易:

import EffectUtils._

object App {
  // calling a Firebase function
  val record: Task[UserRecord] = firebase.getInstance().auth().getUserByEmailAsync(email).toEffect

推荐阅读