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

R Shiny进度条与脚本执行同步问题求助

解决方案

问题分析

你的代码存在两个核心问题:

  1. 进度条动画会先执行完10次来回滚动,才开始运行脚本,这意味着脚本执行时进度条已经停止,不符合你“进度条持续滚动至脚本完成”的需求;
  2. 脚本未执行大概率是路径问题——Shiny应用的工作目录可能和你预期的不一致,导致找不到./Scripts/Scenarios.R文件。

修复步骤与代码

1. 先确认脚本路径正确性

在server函数开头添加代码,打印当前工作目录,确认脚本路径是否存在:

server <- function(input, output, session) {
  print(getwd())  # 打印当前工作目录
  # 后续代码...
}

如果输出的目录下没有Scripts/Scenarios.R,请改用绝对路径(比如source("C:/Projects/MyShinyApp/Scripts/Scenarios.R")),或者用normalizePath确保路径正确:

source(normalizePath("./Scripts/Scenarios.R", mustWork = TRUE))

mustWork = TRUE会在路径不存在时直接报错,帮你快速定位问题。

2. 重构代码实现“进度条持续滚动至脚本完成”

由于Shiny是单线程应用,直接在主线程同时做进度条动画和脚本执行会导致阻塞,需要用future + promises包实现异步执行:

第一步:安装并加载依赖包

install.packages(c("future", "promises"))
library(shiny)
library(future)
library(promises)

# 设置异步后端为multisession
plan(multisession)

第二步:修改server中的observeEvent代码

observeEvent(input$calc_tax_prop_Button, {
  progress <- shiny::Progress$new()
  on.exit(progress$close())

  progress$set(message = "Running Simulation", detail = "Please wait...", value = 0)

  # 标记脚本是否执行完成
  is_done <- reactiveVal(FALSE)

  # 异步执行目标脚本
  future({
    # 这里替换为正确的脚本路径
    source(normalizePath("./Scripts/Scenarios.R", mustWork = TRUE))
    return(TRUE)
  }) %...>% {
    # 脚本执行完成后标记状态
    is_done(TRUE)
  } %>% catch(function(err) {
    # 捕获脚本执行错误,显示通知
    showNotification(paste("Error:", err$message), type = "error", duration = NULL)
    is_done(TRUE)
  })

  # 持续更新进度条,直到脚本完成
  observe({
    req(!is_done())
    # 进度条来回滚动
    for (j in seq(0, 1, by = 0.1)) {
      if (is_done()) break
      progress$set(value = j)
      Sys.sleep(0.1)
    }
    for (j in seq(1, 0, by = -0.1)) {
      if (is_done()) break
      progress$set(value = j)
      Sys.sleep(0.1)
    }
    # 循环触发自身,持续更新
    invalidateLater(100)
  })

  # 脚本完成后显示通知
  observe({
    req(is_done())
    showNotification("Simulation is done!", duration = NULL)
    # 停止进度条更新的observe
    cancelObservers()
  })
})

代码说明

  • 用future把脚本执行放到后台线程,避免阻塞主线程的进度条更新;
  • is_done作为状态标记,控制进度条的循环更新;
  • 添加错误捕获,脚本执行出错时会弹出错误通知;
  • 进度条会持续来回滚动,直到脚本执行完成(无论成功或失败)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:31:14