我正在 Shiny 中进行一些复杂的计算,用户通过 ActionButton 启动。然而,我担心用户在短时间内多次向按钮发送垃圾邮件,这可能会带来大量不必要的计算。我尝试过使用
debounce()
,但它仍然记录所有按钮点击。这是一个代表:
library(shiny)
ui <- fluidPage(
actionButton("start", "Press me")
)
server <- function(input, output, session) {
new_number <- eventReactive(input$start, {
print("Button press registered!")
# sleep to imitate a long calculation
Sys.sleep(1)
runif(1, 1, 1000)
}) %>% debounce(millis = 3000)
observeEvent(new_number(),
print(new_number()))
}
shinyApp(ui, server)
尝试运行应用程序并尽可能快地单击。
它表明按钮被记录为被按下很多次,每次都会停止整个过程。
输出值仅打印一次,而不是单击按钮的次数,我怀疑这可能有用。但我不知道如何注册,例如每秒最多按一个按钮。
一种可能性是使用按钮的
onclick
属性在单击按钮时禁用该按钮,并在您想要的持续时间(在下面的示例中为 3 秒)后重新启用它。
library(shiny)
onclick <- paste(
"var btn = this;",
"btn.setAttribute('disabled', 'disabled');",
"setTimeout(function(){btn.removeAttribute('disabled');}, 3000);"
)
ui <- fluidPage(
actionButton(
"start",
"Press me",
onclick = onclick
)
)
您可以在
observeEvent
上使用 input$start
并保留单击时的时间戳,如果在 3000 毫秒超时之前再次单击则不执行任何操作。
话虽如此,从用户体验的角度来看,我绝对建议禁用该按钮。
library(shiny)
ui <- fluidPage(
actionButton("start", "Press me")
)
server <- function(input, output, session) {
# -- init
ref_timestamp <- reactiveVal(0)
observeEvent(input$start, {
# -- get current timestamp (in milliseconds)
timestamp <- as.numeric(Sys.time())*1000
# -- check timestamp
if(timestamp - ref_timestamp() > 3000){
# -- store new timestamp
ref_timestamp(timestamp)
print("Button press registered!")
# sleep to imitate a long calculation
Sys.sleep(1)
# -- compute
print(runif(1, 1, 1000))}
})
}
shinyApp(ui, server)