2

在我的一个项目中,我必须使用基于回调的异步 API。我想介绍一下cats IO,但我遇到了一些麻烦:

IO.cancelable { cb =>
  val subscription = createSubscription(
     ...,
     (msg: Message) => cb { Right("SomeResult") }
  )
  IO {subscription.unsubscribe()}
}

它看起来很不错,但是我也需要unsubscribe在收到消息后。不幸IO {subscription.unsubscribe()}的是,仅在取消的情况下进行评估。我可以快速解决,但这似乎非常违反直觉:

IO.cancelable { cb =>
  lazy val subscription = createSubscription(
     ...,
     (msg: Message) => cb {
       subscription.unsubscribe() //I can't be really sure if subscription is already initialized
       Right("SomeResult")
     }
  )
  subscribe //I have to ensure evalutaion of lazy val
  IO {subscription.unsubscribe()}
}

我检查了猫效果文档,遗憾的是我没有找到任何可以帮助我解决这个问题的东西。我可以为这个问题想出一些防弹的解决方案,但它看起来很典型,我不敢相信它还没有解决。

有没有简单的方法来实现这种资源释放行为cats

4

1 回答 1

0

试试看Resource

import cats.effect.{ IO, Resource }

val subscriptionResource: Resource[IO, Subscription] =
  Resource.make {
    IO { createSubscription(...) }
  } { subscription =>
    IO { subscription.unsubscribe() }
  }

用作:

subscriptionResource.use { subscription =>
  // your IO routine
}

这是一种(可组合的)方法,可以确保无论出现错误还是成功都会释放您的资源。(虽然,我不记得在取消的情况下会发生什么,因为它是一个技巧主题 - 可能在这种情况下release不会调用块)。

于 2020-03-20T18:23:44.100 回答