如何在Shiny中通过req()判断output$Var存在后执行后续逻辑?
问题:Shiny中如何让后续逻辑仅在耗时输出完成后执行?
我创建了一个需要耗时运行的output$something输出,希望后续流程仅在该输出存在时执行。但直接用req(output$something)会导致应用崩溃,请问有没有办法实现这个需求?示例代码如下:
library(shiny) library(bslib) ui <- fluidPage( navbarPage( theme = bs_theme(bootswatch = "flatly", version = 4), title = 'Methods', tabPanel('One'), ), mainPanel( h1('Hello World'), verbatimTextOutput("something"), verbatimTextOutput("newThing"), # 新增后续输出 br() ) ) server <- function(input, output) { output$something <- renderPrint({ Sys.sleep(5) # 模拟耗时操作 'Test' }) # 注释的代码会导致崩溃 # output$newThing <- renderPrint({ # req(output$something) # # 执行后续逻辑 # }) } shinyApp(ui, server)
解决方案
不能直接对output对象使用req(),因为Shiny的output不是设计用来被其他反应式逻辑直接依赖的。正确的做法是把耗时计算的结果存储在一个reactive变量中,让output$something和后续逻辑都依赖这个变量:
library(shiny) library(bslib) ui <- fluidPage( navbarPage( theme = bs_theme(bootswatch = "flatly", version = 4), title = 'Methods', tabPanel('One'), ), mainPanel( h1('Hello World'), verbatimTextOutput("something"), verbatimTextOutput("newThing"), br() ) ) server <- function(input, output) { # 用reactive变量存储耗时计算的结果 calc_result <- reactive({ Sys.sleep(5) # 模拟耗时操作 'Test' }) # 第一个输出依赖reactive变量 output$something <- renderPrint({ calc_result() }) # 后续逻辑依赖同一个reactive变量,用req判断是否就绪 output$newThing <- renderPrint({ req(calc_result()) # 仅当calc_result有值时执行 "后续逻辑执行完成" }) } shinyApp(ui, server)
原理说明
calc_result是一个reactive对象,只有当它的计算完成并返回值后,依赖它的output$something和output$newThing才会触发更新。req(calc_result())会自动等待calc_result计算完成,只有当它有有效值时,才会执行后续代码,避免了直接依赖output导致的崩溃问题。
内容的提问来源于stack exchange,提问作者dhc
相关产品推荐
相关产品推荐

