You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Resource程序无限循环运行?useForever仅执行一次问题求助

问题分析与解决方案

你的代码存在关键逻辑误解:Resource.eval会把IO操作绑定到Resource的资源获取(acquire)阶段执行,而非使用(use)阶段。调用useForever时,Resource会一次性完成所有acquire步骤——也就是执行一次engine.createSth和一次2秒睡眠——随后进入use阶段,但你的use阶段没有持续执行的逻辑,仅维持资源不释放,因此目标操作只会运行一次。

正确实现方式

要实现「初始化资源后无限循环执行操作」的需求,需将一次性初始化逻辑放到Resource的acquire阶段,将循环执行的业务逻辑放到use阶段。以下是两种清晰的实现写法:

写法1:直接组合初始化与循环

val program: Resource[IO, Nothing] = 
  Resource.eval(engine.createSth).flatMap { _ =>
    // 定义无限循环逻辑:执行操作 → 休眠2秒 → 重复
    val infiniteLoop: IO[Nothing] = 
      IO(engine.doSth) *> IO.sleep(2.seconds) *> infiniteLoop
    Resource.eval(infiniteLoop)
  }

program.useForever.as(ExitCode.Success)

写法2:拆分初始化与循环逻辑

// 仅执行一次的资源初始化Resource
val initResource: Resource[IO, Unit] = Resource.eval(engine.createSth)

// 无限循环执行的业务IO
val taskLoop: IO[Nothing] = 
  for {
    _ <- IO(engine.doSth) // 替换为你需要重复执行的操作
    _ <- IO.sleep(2.seconds)
    _ <- taskLoop
  } yield ()

// 组合资源与循环:先初始化,再持续运行循环
val program: Resource[IO, Nothing] = initResource.flatMap(_ => Resource.eval(taskLoop))

program.useForever.as(ExitCode.Success)

关键说明

  • initResource负责一次性完成资源创建(如engine.createSth),仅在程序启动时执行一次。
  • taskLoop是需要无限重复的业务逻辑,通过递归调用实现循环,每次执行后休眠2秒。
  • useForever会让Resource的use阶段持续运行循环逻辑,不会触发资源释放,从而保持应用持续运行且循环执行目标操作。

内容的提问来源于stack exchange,提问作者LancerX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:45:02