11

Hope someone can help me with this.

Let's say there is a function "example" which is something like

##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()
})

Is there some way to capture the "cat" outputs from the function into renderPrint, periodically? Assuming that this is a long function to process and it would be nice for the user to get some feedbabk. invalidateLater does not work for things that are already within a function (at least it seems that way when I tried it here).

Also, as a secondary problem, writing the code in the above manner would cause renderPrint to capture both the "cat" and the data.frame together, possibly because of the "return".

If anyone could point me in the right direction, it would be most helpful! Thanks!

4

1 回答 1

6

首先,很好的问题我一直在思考这个问题。

由于闪亮是单线程的,因此捕获函数输出并以我所知道的闪亮显示它有点棘手。

解决此问题的方法是使用非阻塞文件连接并运行要在后台捕获输出的函数,同时读取函数输出的文件(检查编辑历史以了解如何执行此操作)。

另一种方法是覆盖 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 的这个问题。

于 2015-10-12T11:29:42.463 回答