看看Tracker.autorun,我想知道它是如何决定哪些变量将形成计算的依赖关系,这主要是有用的。它只选择“反应性”vars,例如:
window.bar = 1
Tracker.autorun (c) =>
bar = window.bar
foo = Session.get('foo')
console.log('autorun', foo, bar)如果我更改Session.set('foo')的值,这将导致计算再次运行。然而,仅仅更改window.bar并不会导致重新运行。如果我使用一个订阅结果(而不是一个集合),这也是有效的,所以我想也是被动的。
是否有更好地理解这种行为的指南?
编辑:
感谢下面的注释,说明计算是可以推断的,因为访问器用于响应vars,因此流星可以跟踪deps。
但是,我需要更清楚一点来理解变量何时被标记。例如,在下面的示例中,subscribe调用位于autorun之外,但它将结果放入数组中。因此,这意味着跟踪器不仅跟踪对(反应性var)访问器方法的调用,还跟踪块中引用的所有变量--即使设置这些方法的调用位于autorun()块之外。
subList = [
Meteor.subscribe("Players"),
Meteor.subscribe("Stuff" )
]
Tracker.autorun (c) =>
subReady = _.filter subList, (item) ->
return item.ready()
allDone = (subList.length == subReady.length)
# this code will rerun when the subs ready() are true也许我应该把这作为一个新问题..。这与这个问题有关。
发布于 2014-10-14 07:55:09
我不是专家,也没读过很多关于它的文章,但我可以试着简单地解释一下。
所有的反应变量都有一个叫做依赖的东西。例如,当创建一个新的ReactiveVar时,就会创建一个新的依赖项。看这里。
要从反应性变量中检索值,必须调用一个函数。在"getter“中,依赖项被指示要记住它有依赖项。例如,请看这里 For ReactiveVar.get。
若要更改反应性变量的值,必须调用函数。在该"setter“中,依赖项被通知发生了更改,并且指示所有依赖于依赖项的函数都必须重新运行。例如,请看这里 For ReactiveVar.set。
不复杂,对吧?好吧,这只是简单的部分,现在剩下的就是建设基础设施,使它工作:)这是更难和更复杂的解释。
反应性变量本身并不是反应性的,它们必须在反应环境中进行评估才能成为反应性变量。通过调用Tracker.autorun创建一个反应性环境。看这里。
当调用Tracker.autorun时,传递给它的函数将在新的反应性环境中执行,使用depend方法通知的所有依赖项都将被环境跟踪。当您调用aDependency.depend时,将执行这一功能,它会将依赖项添加到环境列表中,而不是它所依赖的依赖项。
当反应性变量更改其值时,将执行这一功能。它告诉环境它所依赖的一个反应变量已经改变,并使环境中的所有依赖项无效。在此之后,将重新运行传递给Tracker.autorun的整个函数,并跟踪新的依赖项。
你明白大局了吗?它的实现比我所解释的要复杂一些,但我认为这就是它的工作方式。
发布于 2014-10-14 07:46:28
注意,每当您访问一个反应性变量时,它都是通过函数调用来实现的,比如Session.get(...)、collection.find(...).fetch()或Meteor.status()。像Session.get这样的函数不仅获得会话变量的值,而且还注册了对当前计算的依赖关系(当前计算的范围是动态的,因此Session.get知道它是从自动运行中调用的)。
下面是如何使用Tracker.Dependency实现自己的反应性变量
dependency = new Tracker.Dependency()
currentValue = null
@setCurrentValue = (newValue) ->
if newValue isnt currentValue
# rerun computations which depend on this Dependency
dependency.changed()
currentValue = newValue
@getCurrentValue = ->
# register this dependency on the current computation (if there is one)
dependency.depend()
return currentValue下面是你可以使用的方法:
setCurrentValue("hello")
Tracker.autorun ->
console.log(getCurrentValue())
# => "hello" printed
setCurrentValue("goodbye") # => "goodbye" printed要获得更多信息,您可以查看本指南:https://meteor.hackpad.com/DRAFT-Understanding-Deps-aAXG6T9lkf6 (请注意,跟踪器最初在较早版本的Meteor中被称为Dep)。
https://stackoverflow.com/questions/26354582
复制相似问题