2015-10-20 43 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