闪亮的承诺未来不适用于 eventReactive
Shiny promises future is not working on eventReactive
我有一个 inputButton,当您单击它时,对 mysql 数据库的 2 个查询已完成。一个是重的(10秒以上),一个是轻的(小于0.01秒获取数据)
因为我想在闪亮的应用程序上显示这个查询的结果,所以我打算使用 Promises 和 Future 包进行异步加载。
在我向您展示的代码示例中,我使用函数 heavyFunction 模拟了 SQL 查询,旨在模拟繁重的查询,并且轻一次加载。
问题是这段代码对我不起作用,因为轻查询的结果在重查询完成后才会显示。
注意:在 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)
我做错了什么?
欢迎来到 SO!
This 个帖子讨论了同样的问题。
另请参阅 Joe Cheng 在 GitHub 上的详细 [=16=]。
您遇到的主要问题反映在他的以下陈述中:
The goal, at least for this release of Shiny, is not to allow this
kind of intra-session responsiveness, but rather, inter-session; i.e.,
running an async operation won't make its owning session more
responsive, but rather will allow other sessions to be more
responsive.
但是,有一些方法可以通过 运行 后台 R 进程中的未来来解决此行为,例如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)
这里最重要的一点是要意识到,你不应该直接 return 你的未来,否则它会阻止所有其他行动 - 观察者 return 什么都没有,它只有触发回调函数的副作用。
我有一个 inputButton,当您单击它时,对 mysql 数据库的 2 个查询已完成。一个是重的(10秒以上),一个是轻的(小于0.01秒获取数据)
因为我想在闪亮的应用程序上显示这个查询的结果,所以我打算使用 Promises 和 Future 包进行异步加载。
在我向您展示的代码示例中,我使用函数 heavyFunction 模拟了 SQL 查询,旨在模拟繁重的查询,并且轻一次加载。
问题是这段代码对我不起作用,因为轻查询的结果在重查询完成后才会显示。
注意:在 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)
我做错了什么?
欢迎来到 SO!
This 个帖子讨论了同样的问题。
另请参阅 Joe Cheng 在 GitHub 上的详细 [=16=]。
您遇到的主要问题反映在他的以下陈述中:
The goal, at least for this release of Shiny, is not to allow this kind of intra-session responsiveness, but rather, inter-session; i.e., running an async operation won't make its owning session more responsive, but rather will allow other sessions to be more responsive.
但是,有一些方法可以通过 运行 后台 R 进程中的未来来解决此行为,例如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)
这里最重要的一点是要意识到,你不应该直接 return 你的未来,否则它会阻止所有其他行动 - 观察者 return 什么都没有,它只有触发回调函数的副作用。