如何在R Shiny中使操作不间断

yif*_*yan 8 r shiny

在我闪亮的应用程序中,我有一个输出,该输出应不断更新。但是,每当我执行长时间运行的计算时,输出就会暂停。我的问题是:如何使输出连续不断地运行?

请查看下面的简短演示:时钟每隔一秒刷新一次,但是如果我单击运行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)

我试图使用futurepromises让长时间运行的进程异步运行,但是它不起作用。哪里错了?有没有更好的方法可以达到这个目的?

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)

任何帮助表示赞赏!

yif*_*yan 2

感谢@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)