Shiny承诺未来不会在eventReactive上运作

时间:2018-11-21 07:17:21

标签: r shiny future

我有一个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)

我做错了什么?

1 个答案:

答案 0 :(得分:3)

欢迎您!

This主题讨论了相同的问题。

另请参阅Joe Cheng在GitHub上提供的详细answer

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

  

至少对于此版本的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)

这里最重要的一点是要意识到,您不应该直接返回自己的未来,否则它将阻止所有其他操作-观察者什么也不返回,它只具有触发回调函数的副作用。 / p>