在我闪亮的应用程序中,我有一个输出,该输出应不断更新。但是,每当我执行长时间运行的计算时,输出就会暂停。我的问题是:如何使输出连续不断地运行?
请查看下面的简短演示:时钟每隔一秒刷新一次,但是如果我单击运行5秒钟的按钮,时钟将暂停。
library(shiny)
ui <- fluidPage(
actionButton("button","Expensive calcualtion(takes 5 seconds)"),
tags$p("Current Time:"),
textOutput("time"),
tags$p("Result from clicking button:"),
textOutput("result")
)
server <- function(input, output, session) {
output$time <- renderText({
invalidateLater(1000)
as.character(Sys.time())
})
observeEvent(input$button,{
Sys.sleep(5)
output$result <- renderText(runif(1))
})
}
shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)
我试图使用future并promises让长时间运行的进程异步运行,但是它不起作用。哪里错了?有没有更好的方法可以达到这个目的?
library(shiny)
library(future)
library(promises)
plan("multisession")
ui <- fluidPage(
actionButton("button","Expensive calcualtion(takes 5 seconds)"),
tags$p("Current Time:"),
textOutput("time"),
tags$p("Result from clicking button:"),
textOutput("result")
)
server <- function(input, output, session) {
output$time <- renderText({
invalidateLater(1000)
as.character(Sys.time())
})
process <- eventReactive(input$button,{
future({
Sys.sleep(5)
runif(1)
})
})
output$result <- renderText(process())
}
shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏!
感谢@Shree 指出解决方案。看完郑乔的回复。看来关键是:
通过不让 Promise 成为最后一个表达式来隐藏 Shiny 的异步操作。
该问题是通过创建一个反应值并将承诺分配给它作为observeEvent副作用来解决的。
server <- function(input, output, session) {
output$time <- renderText({
invalidateLater(1000)
as.character(Sys.time())
})
process <- reactiveVal()
observeEvent(input$button,{
output$isbusy <- renderText("busy") # a simple busy indicator
future({
Sys.sleep(5)
runif(1)
}) %...>%
process()
# Hide the async operation from Shiny by not having the promise be the last expression
NULL # important
})
output$result <- renderText({
output$isbusy <- renderText("") # a simple busy indicator
process()
})
}
Run Code Online (Sandbox Code Playgroud)