Ответ 1
Yihui предложил использовать withCallingHandlers
, и это действительно позволило мне решить. Я не был уверен, как использовать эту функцию таким образом, чтобы это было именно то, что мне нужно, потому что моя проблема заключалась в том, что у меня была функция, которая печатала несколько сообщений по одному за раз, и с использованием наивного подхода печаталось только последнее сообщение. Вот моя первая попытка (которая работает, если у вас есть только одно сообщение):
foo <- function() {
message("one")
message("two")
}
runApp(shinyApp(
ui = fluidPage(
actionButton("btn","Click me"),
textOutput("text")
),
server = function(input,output, session) {
observeEvent(input$btn, {
withCallingHandlers(
foo(),
message = function(m) output$text <- renderPrint(m$message)
)
})
}
))
Обратите внимание, как выводится только two\n
. Поэтому моим окончательным решением было использование функции html
из пакета shinyjs
(отказ от ответственности: я написал этот пакет), что позволяет мне изменять или добавлять к HTML внутри элемента. Он работал отлично - теперь оба сообщения были распечатаны в режиме реального времени.
foo <- function() {
message("one")
Sys.sleep(0.5)
message("two")
}
runApp(shinyApp(
ui = fluidPage(
shinyjs::useShinyjs(),
actionButton("btn","Click me"),
textOutput("text")
),
server = function(input,output, session) {
observeEvent(input$btn, {
withCallingHandlers({
shinyjs::html("text", "")
foo()
},
message = function(m) {
shinyjs::html(id = "text", html = m$message, add = TRUE)
})
})
}
))