希望有人能帮助我。
让我们说有一个功能"示例"这就像
##function from a package
example<-function(f){
#does something
cat("step 1 done....")
# etc etc
cat("step 2 done....")
return(some_data_frame)
}
##server ui code
example2<-reactive({
if(input$some_action_button==0)
return()
result<-isolate(example(input$f1))
return(result)
})
output$f2<-renderPrint({
example2()
})
有没有办法捕捉&#34; cat&#34;函数输出到renderPrint,定期?假设这是一个很长的处理功能,用户可以获得一些feedbabk。 invalidateLater不适用于函数中已有的东西(至少在我在这里尝试的时候看起来就是这样)。
另外,作为次要问题,以上述方式编写代码会导致renderPrint同时捕获&#34; cat&#34;和data.frame在一起,可能是因为&#34; return&#34;。
如果有人能指出我正确的方向,那将是最有帮助的!谢谢!
答案 0 :(得分:5)
首先,我一直在思考这个问题。
因为有光泽是单线程的,所以捕获函数输出有点棘手,并且根据我的知识显示它。
解决此问题的方法是使用非阻塞文件连接并在读取函数输出文件时运行要从后台捕获输出的函数(检查编辑历史记录以查看如何执行此操作)
执行此操作的另一种方法是覆盖cat函数以写入stderr(只需使用cat
切换message
)并捕获函数输出,如下所示:
library(shiny)
library(shinyjs)
myPeriodicFunction <- function(){
for(i in 1:5){
msg <- paste(sprintf("Step %d done.... \n",i))
cat(msg)
Sys.sleep(1)
}
}
# Override cat function
cat <- message
runApp(shinyApp(
ui = fluidPage(
shinyjs::useShinyjs(),
actionButton("btn","Click me"),
textOutput("text")
),
server = function(input,output, session) {
observeEvent(input$btn, {
withCallingHandlers({
shinyjs::text("text", "")
myPeriodicFunction()
},
message = function(m) {
shinyjs::text(id = "text", text = m$message, add = FALSE)
})
})
}
))
此示例主要基于daattali的this问题。