scala - 使用 cat-effect 的 Timer 实现可取消的 setInterval
问题描述
这是我尝试过的,但在第一次睡眠完成后无法取消。
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
?
解决方案
在Fabio Labella的帮助下,我认识到
F.liftIO(F.runAsync(F.suspend(run))(_ => IO.unit)) *> fa
runAsync
只是让下一个递归调用在后台运行并且不可取消,所以我不得不fa
在后台进行,就像这样
F.liftIO(F.runAsync(fa)(_ => IO.unit)) *> F.suspend(run)
推荐阅读
- scala - 为什么拆分在产量理解scala中不起作用
- python - 我如何在 django 中测试这个 url
- python - Python dict.keys() 有密钥,但没有它
- javascript - 来自 react-native-elements 的样式卡:垂直对齐标题和图标
- c - 如何将 2 个数组传递给一个函数,让用户在这 2 个数组中写一些东西,并将它们都返回给 C 中的程序?
- r - 根据 R 中的多个 ffields 比较列值中的字符串值
- bash - 在bash中对数组进行数字排序
- c# - C# Excel VSTO OLE DB 参数错误必须声明标量变量
- git - 在将我的分支与本地仓库中的 Master 合并,然后在 Github 中推送到远程源
- c# - 如何在我的 Discord Bot 中使用数据库?(使用 Discord.Net 和 psotgresql)