看看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
并不会导致重新运行。如果我使用订阅结果(不是集合),这也有效,所以我猜也是反应性的。
是否有任何指南可以更好地理解这种行为?
感谢下面的评论,澄清计算是可以推断的,因为访问器用于反应变量,因此流星可以跟踪deps。
但是我需要更清楚一点来理解var被标记的时间。例如,在下面的示例中,subscribe
调用位于autorun
之外,但它将结果放入数组中。这意味着Tracker不仅跟踪对(reactive 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
也许我应该将其添加为一个新问题......它与this question有关。
答案 0 :(得分:5)
我不是专家,也没有多多关于它的内容,但我可以尝试简要解释一下。
所有反应变量都有一个称为依赖的东西。例如,当创建新的ReactiveVar
时,会创建新的依赖关系。 See here
要从反应变量中检索值,必须调用函数。在“getter”中,指示依赖项记住它具有依赖性。例如,ReactiveVar.get
的{{3}}。
要更改反应变量的值,必须调用函数。在“setter”中,依赖关系被通知某些内容已发生变化,并且表明依赖于依赖项的所有函数必须重新运行。例如,ReactiveVar.set
的{{3}}。
不复杂吧?嗯,这只是一个简单的部分,现在剩下的就是建立使其工作的基础设施:)这就更难解释了。
反应变量本身不具有反应性;必须在反应环境中对它们进行评估才能产生反应。通过调用Tracker.autorun
创建响应环境。 see here
当您调用Tracker.autorun
时,传递给它的函数将在新的响应环境中执行,并且环境将跟踪反应变量通过depend
方法通知的所有依赖项。当您调用aDependency.depend
时,将执行see here,并且它会依赖于它依赖的依赖项将依赖项添加到环境列表中。
当反应变量改变其值时,将执行See here。它告诉环境它所依赖的一个反应变量已经改变,并使环境中的所有依赖项无效。发生这种情况后,将重新运行传递给Tracker.autorun
的整个函数,并跟踪新的依赖项。
你了解全局吗?它的实现比我解释的要复杂一些,但我认为它的工作方式很有用。
答案 1 :(得分:4)
请注意,无论何时访问反应变量,都是通过函数调用,如Session.get(...)
,collection.find(...).fetch()
或Meteor.status()
。类似Session.get
的函数不仅获取Session变量的值,而且还注册对当前计算的依赖(当前计算是动态范围的,因此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(请注意,Tracker最初在旧版Meteor中称为Deps)