cats效果:避免在t=>unit的外部侦听器上调用unsaferun

mm5n2pyu  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(275)

我使用的外部api提供:

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

我的听众返回:

IO[Unit]

有没有一种方法可以注入我的听众而不需要调用unsaferun?

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

mctunoxg1#

IO 不是你听众的唯一容器。从cats效果文档:

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 :
增加一些影响到 IO 使用 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开始启动整个组合副作用链。使用 unsafeRunSync 或类似的功能 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] 你可以直接执行 IO 得到 A . 你应该使用 IO 当您的应用程序尚未执行完毕时。如果是这样,您可以使用 unsafeRunSync .
我的意思是你应该不使用 unsafeRunSync 不止一次,我猜,你的签名

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

不应使用 IO api,但非常类似于 Async[F[_]] api,看看函数 async :

/**
 * Creates a simple, non-cancelable `F[A]` instance that
 * executes an asynchronous process on evaluation.
 *
 * The given function is being injected with a side-effectful
 * callback for signaling the final result of an asynchronous
 * process.
 *
 * This operation could be derived from [[asyncF]], because:
 *
 * {{{
 *   F.async(k) <-> F.asyncF(cb => F.delay(k(cb)))
 * }}}
 *
 * As an example of wrapping an impure async API, here's the
 * implementation of [[Async.shift]]:
 *
 * {{{
 *   def shift[F[_]](ec: ExecutionContext)(implicit F: Async[F]): F[Unit] =
 *     F.async { cb =>
 *       // Scheduling an async boundary (logical thread fork)
 *       ec.execute(new Runnable {
 *         def run(): Unit = {
 *           // Signaling successful completion
 *           cb(Right(()))
 *         }
 *       })
 *     }
 * }}}
 *
 * @see [[asyncF]] for the variant that can suspend side effects
 *      in the provided registration function.
 *
 * @param k is a function that should be called with a
 *       callback for signaling the result once it is ready
 */
def async[A](k: (Either[Throwable, A] => Unit) => Unit): F[A]

集中注意力 listen 应该在你的申请中做的,并选择正确的签名。
有用链接:
猫效应
异步类型类

相关问题