Добро пожаловать в SO!
В этой теме обсуждается та же проблема.
Пожалуйста, также посмотрите подробный ответ от Джо Чена на GitHub.
Основная проблема, с которой вы сталкиваетесь, отражена в его следующем утверждении:
Цель, по крайней мере для этого выпуска Shiny, - не допустить такого рода внутрисессионного реагированияа точнее межсессионный;то есть, выполнение асинхронной операции не сделает свой собственный сеанс более отзывчивым, а скорее позволит другим сеансам быть более отзывчивым.
Однако есть способы обойти это поведение, запустив будущеев фоновом процессе 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)
Самый важный моментздесь нужно понимать, что вы не должны возвращать свое будущее напрямую, иначе оно заблокирует все другие действия - наблюдатель ничего не возвращает, у него есть только побочный эффект запуска функции обратного вызова.