闪亮的承诺未来不适用于 eventReactive

jff*_*jff 4 future r shiny

我有一个 inputButton,当您单击它时,完成了对 mysql 数据库的 2 次查询。一个是重的(超过 10 秒),另一个是轻的(小于 0.01 秒获取数据)。

由于我想在闪亮的应用程序上显示此查询的结果,因此我打算使用 Promises 和 Future 包进行异步加载。

在我向您展示我的代码的示例中,我使用函数HeavyFunction模拟了 SQL 查询,该函数旨在模拟繁重的查询和一次加载的ligth

问题是这段代码对我不起作用,因为在完成重查询之前不会显示轻查询的结果。

注意:在 Rstudio 控制台中,此代码完美运行...

library(future)
library(promises)
plan(multiprocess)

heavyFunction <- function(n){
  Sys.sleep(n)
  print(n)
}


ui <- fluidPage(
  actionButton("go","Show the data"),
  textOutput("result0sec"),
  textOutput("result10sec")

)

server <- function(input,output,session){


  data0 <- eventReactive(input$go,{
    heavyFunction(0)


  })

  data10 <- eventReactive(input$go,{
    heavyFunction(10)


  })
  output$result0sec <- renderText({
  data <- data0()
  future(data)%...>%print()
  })


  output$result10sec <- renderText({
    data <- data10()
    print(data)
  })




}
shinyApp(ui,server)
Run Code Online (Sandbox Code Playgroud)

我做错了什么?

ism*_*gal 5

欢迎来到 SO!

这个线程讨论了同样的问题。

另请参阅GitHub 上 Joe Cheng的详细回答

您遇到的主要问题反映在他的以下声明中:

至少对于这个 Shiny 版本,目标不是允许这种会话内响应,而是会话间响应;即,运行异步操作不会使其拥有的会话更具响应性,而是允许其他会话更具响应性。

但是,有一些方法可以通过在后台 R 进程中运行 future 来解决此行为,例如library(callr)或更方便library(future.callr),它是plan(callr).

这是您的代码的工作版本:

library(future)
library(promises)
library(future.callr)
plan(callr)

heavyFunction <- function(n) {
  Sys.sleep(n)
  print(n)
}

ui <- fluidPage(
  br(),
  actionButton("go", "Show the data"),
  br(), br(),
  textOutput("result0sec"),
  textOutput("result10sec")
)

server <- function(input, output, session) {
  futureData <- reactiveValues(data10 = NULL)

  data0 <- eventReactive(input$go, {
    heavyFunction(0)
  })

  observeEvent(input$go, {
    myFuture <- future({
      heavyFunction(5)
    })

    then(
      myFuture,
      onFulfilled = function(value) {
        futureData$data10 <<- value
      },
      onRejected = NULL
    )
    return(NULL)
  })

  output$result0sec <- renderText({
    data0()
  })

  output$result10sec <- renderText({
    req(futureData$data10)
  })
}

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

这里最重要的一点是要意识到,你不应该直接返回你的未来,否则它会阻止所有其他动作——观察者什么都不返回,它只有触发回调函数的副作用。