R中带有Future包的异步编程

时间:2019-06-21 13:16:58

标签: r asynchronous promise future

我是使用Future Package在R中进行异步编程的新手,因此需要一些帮助。我正在尝试使用支持异步编程的rshiny构建一个简单的应用程序。因此,我的代码为直方图,滑块,简单的文本打印和read.csv函数,用于读取大型CSV文件。因此,我的计划是在我的read.csv函数使用R中的future软件包在后台运行之前,我想控制其他应用程序。

But my code waits for the CSV file to read. Any help will be appreciated. 

    library(promises)
library(future)
library(shinydashboard)
library(shiny)
library(tidyverse)
plan(multiprocess)

    enter code here
#UI parts
ui <- dashboardBody(fluidRow(box(tableOutput("input1")),
                             box(textOutput("input2"))),

                    fluidRow(box(
                      sliderInput(
                        inputId = "bins",
                        label = "Number of bins:",
                        min = 1,
                        max = 5,
                        value = 2
                      )
                    ),
                    box(plotOutput(outputId = "distPlot"))),


                    fluidRow(box(
                      sliderInput(
                        "slider2",
                        label = h3("Slider Range"),
                        min = 0,
                        max = 100,
                        value = c(40, 60)
                      )
                    ),
                    box(verbatimTextOutput("range"))))

#server part
server <- function(input, output, session) {
  output$input1 <- renderTable({
    promise <- future((read.csv("data/sample_large.csv")))
    promise %...>% head() %...>% print()
  })

  output$input2 <- renderText({
    print("hello")
  })
  output$distPlot <- renderPlot({
    dist <- rnorm(input$bins)
    hist(dist)
  })
  output$range <- renderPrint({
    input$slider2
  })

}
shinyApp(ui = dashboardPage(dashboardHeader(),
                            dashboardSidebar(),
                            ui),
         server = server)

1 个答案:

答案 0 :(得分:0)

您期望的行为是您在UI的其余部分没有加载直到评估了promise时所经历的行为。在Promise软件包中将其解释为所谓的“闪亮刷新周期”,并在herehere中进行了详细说明。

仅在所有输出完成执行后,它们才被发送回Shiny以更新UI。您可能希望/更喜欢在准备好输出后立即对其进行渲染,但是不幸的是,这不是Shiny的操作方式。

如第二个链接中所述,您可以“欺骗”认为所有输出均已执行,然后在承诺评估后使用反应性值触发最终更新:

#server part
server <- function(input, output, session) {

  data <- reactiveVal()

# Return NULL from this operation so Shiny 'thinks' the output is evaluated
  observe({
    data(NULL)
    future({read.csv("data/sample_large.csv")}) %...>%
      data() #Assign to data
    NULL
  })

# When data() is updated as a side effect of our promise the table will be updated
  output$input1 <- renderTable({
    req(data()) %>%
      head(5) %>%
      print()
  })

# in the mean time all outputs will be judged to be complete so can be rendered
  output$input2 <- renderText({
    print("hello")
  })
  output$distPlot <- renderPlot({
    dist <- rnorm(input$bins)
    hist(dist)
  })
  output$range <- renderPrint({
    input$slider2
  })

}
shinyApp(ui = dashboardPage(dashboardHeader(),
                            dashboardSidebar(),
                            ui),
         server = server)