使用cats-effect的Timer实现可取消的setInterval

时间:2018-08-17 01:38:42

标签: scala scala-cats cats-effect

这是我尝试过的方法,但是第一次睡眠结束后不能取消。

import cats.syntax.all._
import cats.effect._
import scala.concurrent.duration._
import scala.language.higherKinds

object Foo {
  def setInterval[F[_]](duration: FiniteDuration)(
    fa: F[Unit]
  )(implicit F: ConcurrentEffect[F], T: Timer[F]): F[IO[Unit]] = {
    def run: F[Unit] = {
      T.sleep(duration) *>
        F.liftIO(F.runAsync(F.suspend(run))(_ => IO.unit)) *> fa
    }
    F.liftIO(F.runCancelable(run)(_ => IO.unit))
  }
}

如何实现真正可取消的setInterval

1 个答案:

答案 0 :(得分:1)

Fabio Labella的帮助下,我认识了

F.liftIO(F.runAsync(F.suspend(run))(_ => IO.unit)) *> fa

runAsync只是使下一个递归调用在后台运行且不可撤销,因此我不得不在后台进行fa,就像这样

F.liftIO(F.runAsync(fa)(_ => IO.unit)) *> F.suspend(run)