在R Shiny中用自身更新响应式值遇无限递归问题求助
解决Bugzilla仪表盘的无限递归问题
问题根源
你代码里的无限递归是因为重复定义了ckbdata这个reactive对象,且在第二个reactive中直接调用了ckbdata()——此时ckbdata已经指向当前这个reactive,每次计算都会触发自身重新执行,陷入无限循环。
修正方案
改用reactiveVal存储本地Bug数据(它支持手动修改值),配合observe监听定时器触发更新逻辑:
# 初始化定时器,每10秒触发一次 poll <- reactiveTimer(intervalMs = 10000) # 用reactiveVal存储本地Bug数据,初始加载全量数据 ckbdata <- reactiveVal(get_bugzilla()) # 监听定时器,执行增量更新 observe({ # 触发定时器依赖,每10秒执行一次 poll() # 获取当前本地存储的最新变更时间 current_data <- ckbdata() latest_time <- max(current_data[['last_change_time']]) # 查询该时间点之后的变更数据 new_data <- get_bugzilla(latest_time) if (nrow(new_data) > 0) { # 移除本地数据中已被更新的Bug(用id匹配) updated_data <- current_data[!(current_data$id %in% new_data$id), ] # 合并新数据到本地副本 updated_data <- rbind(updated_data, new_data) # 更新reactiveVal中的数据 ckbdata(updated_data) } })
关键改动说明
- 使用
reactiveVal替代重复定义的reactive:reactiveVal是可变的响应式容器,允许在observe中手动更新其值,避免了reactive对象的自引用循环。 - 用
observe处理定时更新逻辑:observe会监听定时器的触发事件,每次触发时执行增量查询和本地数据更新,不会引发递归。 - 修正了数据判断:原代码用
length(new)判断是否有新数据,改为nrow(new_data)更准确(因为get_bugzilla返回的应该是数据框)。
内容的提问来源于stack exchange,提问作者littlefeltfangs
相关产品推荐
相关产品推荐

