如何将可取消的订阅转换为Cat的IO

问题描述 投票:2回答:1

在我的一个项目中,我必须使用基于回调的异步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实现此资源释放行为?

scala scala-cats cats-effect
1个回答
0
投票

尝试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块不会被调用。)

© www.soinside.com 2019 - 2024. All rights reserved.