2015-10-20 44 views
2

我试图构建一个闪亮的应用程序,通过不同的渲染*函数输出几个结果。强制渲染已计算的无功元素

问题是,其中一个结果需要一些时间来计算。所以我想闪亮的尽快呈现快速结果。

下面是一些代码来说明

# ui.R 
library(shiny) 

shinyUI(fluidPage(
    textOutput("res1"), 
    textOutput('res2') 
)) 

# server.R 
library(shiny) 

shinyServer(function(input, output) { 

    output$res1 = renderText({ 
     "shows up instantly" 
    }) 

    output$res2 = renderText({ 
      Sys.sleep(3) 
      "shows up after 3 sec" 
    }) 
}) 

现在,网页保持为空3秒,这两个元件被同时呈现。

我的问题如下:是否有可能强制output$res1output$res2之前执行,并且在长计算开始之前将其结果发送到浏览器?

回答

2

我找到了一个解决方法。这个想法是强制所有render*函数在启动长计算之前将其结果发送给浏览器。

在下面的代码中,两个文本区域立即出现,第二个文本区域在3秒后更新。

shinyServer(function(input, output,session) { 

    status=reactiveValues(res1IsDone=FALSE,res2HasRendered=FALSE) 

    output$res1 = renderText({ 
     status$res1IsDone = TRUE 
     "shows up instantly" 
    }) 

    output$res2 = renderText({ 
     if(isolate(!status$res1IsDone || !status$res2HasRendered)) { 
      status$res2HasRendered = TRUE 
      invalidateLater(100,session) 
      "wait" 
     } else { 
      Sys.sleep(3) 
      "shows up after 3 sec" 

     } 
    }) 
}) 

据我了解,有光泽是单线程并将结果发送回一旦所有的render*功能被执行一次浏览器(或当所有的失效都解决了?)。

2

退房invalidateLater否则,如果你只是想呈现文本可以直接发送短信给使用客户端:

# ui.R 
library(shiny) 

ui <- shinyUI(fluidPage(
    tags$head(
    tags$script(
     HTML(" 
      Shiny.addCustomMessageHandler ('print',function (message) { 
       $('#'+message.selector).html(message.html); 
       console.log(message); 
      }); 
      ") 
    ) 
), 
    textOutput("res1"), 
    textOutput('res2') 
)) 

# server.R 
server <- shinyServer(function(input, output, session) { 
    session$sendCustomMessage(type = 'print', message = list(selector = 'res1', html = "shows up instantly")) 
    Sys.sleep(3) 
    session$sendCustomMessage(type = 'print', message = list(selector = 'res2', html = "shows up after 3 sec")) 
}) 

shinyApp(ui = ui, server = server) 
+0

谢谢!然而,它不能解决我的问题,因为更复杂的输出。 – jey1401