强制渲染已计算的反应元素

jey*_*401 5 r shiny

我正在尝试构建一个闪亮的应用程序,通过不同的 render* 函数输出多个结果。

问题是其中一个结果需要一些时间来计算。所以我希望shiny能够尽快渲染出快速的结果。

这是一些代码来说明

# 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"
    })
})
Run Code Online (Sandbox Code Playgroud)

目前,网页保持空白 3 秒,两个元素同时呈现。

我的问题如下:是否可以强制output$res1执行之前output$res2并将其结果发送到浏览器之前进行长时间的计算开始?

jey*_*401 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"

        }
    })
})
Run Code Online (Sandbox Code Playgroud)

render*据我了解,shiny 是单线程的,一旦所有函数执行一次(或者所有失效都解决了?),结果就会发送回浏览器。