在我的一个项目中,我必须使用基于回调的异步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-effects文档,可惜我没有找到任何可以帮助我解决这个问题的东西。我可以想到一些针对此问题的防弹解决方案,但看起来如此典型,以至于我不敢相信它尚未解决。
是否有任何简单的方法可以使用cats
实现此资源释放行为?
尝试Resource
s:
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
块不会被调用。)