什么是reactive source、reactive conductor和reactive endpoint?reactive conductor的主要作用是什么?请列举几个场景。
reactive source是一个信号,当这个信号改变时,会通知所有包含这个信号的下游重新执行
reactive conductor:reactive source和reactive endpoint之间的操作,主要用来封装性能较低的操作,避免重复运算。常用场景有:访问数据库、读取文件、执行低性能操作等。
reactive endpoint:当包含的信号改变时,重新执行,并且能要求上游依赖重新执行。
下面的代码会报错,怎么修改?
shinyServer(function(input, output) {
# Will give error
currentFib <- fib(as.numeric(input$n))
output$nthValue <- renderText({ currentFib })
output$nthValueInv <- renderText({ 1 / currentFib })
})
请详述上面代码的执行过程
基本概念invalidation flag:clean,表示状态已经更新;dirty,包含的reactive source取值改变,需要重新执行。
当reactive source input$n
发生了改变,它的下游节点currentFib
变为dirty,input$n
与currentFib
的箭头删除。currentFib
变为dirty,立马又invalidate它的所有下游节点output$nthValue
和output$nthValueInv
,它们之间的箭头也删除。此时如果再改变reactive source的取值,因为箭头不存在(依赖关系暂时消除),不会再引起下游状态的改变。
Shiny会自动触发事件,让处于dirty状态的reactive endpoint重新执行。output$nthValue
和output$nthValueInv
都是endpoint,都会自发地重新执行,它们之间的先后执行顺序没有约束,完全是随机的。我们假设output$nthValue
碰巧先于output$nthValueInv
执行了,则它会向currentFib
请求数据,output$nthValue
和currentFib
的箭头重新建立。因为currentFib
的状态是dirty,它会重新执行,向input$n
请求数据,input$n
和currentFib
的箭头重新建立。currentFib
获取input$n
的数据后,执行完毕,将状态更新为clean,并向output$nthValue
返回取值。output$nthValue
执行完成,更新状态为clean。
接着处于dirty状态的output$nthValueInv
重新执行,向currentFib
请求数据,二者之间的箭头重新建立。currentFib
已经处于clean状态,向output$nthValueInv
直接返回数据。output$nthValueInv
执行完毕,将状态更新为clean。
请注意,reactive conductor采用的是lazy evaluation,即它所依赖的reactive source发生改变时,不会立即重新执行,会等待下游触发它执行。如果没有下游来触发它,reactive conductor是不会执行的,即使所包含的reactive source已发生改变。
observe vs reactive
二者都可以读取reactive values,执行reactive expression,当依赖改变时会自动重新执行。区别在于,observe没有返回值,reactive有返回值。因此reactive的返回值可以作为输入用于搭建新的reactive expression,而observe是整个reactive依赖链的终端。
另一个区别是reactive是lazy evaluation,而observe是eager evaluation。当observe依赖的reactive source发生改变时,会立刻重新执行。
isolate
只读取reactive value的取值,不建立与reactive value的依赖。
observe vs observeEvent
observeEvent是对observe和isolate的封装,用于模仿事件驱动编程。observeEvent的使用场景是当某个事件发生时执行一个操作。
observe执行的时机是expression里包含的reactive value取值发生改变时。observeEvent执行的时机是第一个参数reactive value所代表事件发生改变时,与expression里的reactive value是否发生改变无关。
也就是说,reactive invalidate机制在observeEvent这里是无效的,这里只考虑依赖的事件是否发生改变。
observeEvent vs eventReactive
observeEvent无返回值,eventReactive有返回值。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。