Cats 效果:避免在 T => Unit 的外部侦听器上调用 unsafeRun

问题描述

我使用的外部 API 提供:

def listen(listener: ResponseType => Unit): Handle

我的听众返回:

IO[Unit]

有没有办法在不需要调用 unsafeRun 的情况下注入我的监听器?

listen(msg => myListener(msg).unsafeRunSync())

解决方法

IO 不仅是您的听众的容器。来自 cats-effect 文档:

A pure abstraction representing the intention to perform a side effect,where the result of that side effect may be obtained synchronously (via return) 
or asynchronously (via callback)

这意味着 IO 不包含某些值,而是包含执行某些副作用的意图。

此处是使用 IO 的最常用方法:

  1. 使用 IO(这种方式命名为 composition)向包含 flatMap 的内容添加一些效果
val ioA: IO[A] = ??? // you have some side effect returning A
// here you can have some different side effect returning B: work with DB,read some resource or so on
def aToIOB(a: A): IO[B] = ??? 
val ioB: IO[B] = ioA.flatMap(aToIOB)
  1. 启动整个组合链副作用1.使用unsafeRunSync或运行{{1}的类似函数}}。它应该在您的应用程序中调用一次,并且通常在宇宙的尽头(在您的程序的末尾)。
IO

因此,当您看到 // this line launches execution of ioA and aToIOB and will return value of B with side-effects val b: B = ioB.unsafeRunSync() 时,您应该记住它与 IO[A]Option[A] 不同,您只需执行 List[A] 即可获得 {{1} }.当您的应用程序未执行结束时,您应该使用 IO 的组合。如果是这样,您可以使用 A 运行它。

我的意思是你应该在不超过一次使用 IO 的情况下构建你的应用程序,我猜,你的签名

unsafeRunSync

不应该使用unsafeRunSync API,但非常类似于def listen(listener: ResponseType => Unit): Handle API,看看函数IO

Async[F[_]]

尽量将 async 应该在您的应用程序中做的事情集中起来,并选择正确的签名。

有用的链接:

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...