首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tracker.autorun如何选择它的计算?

Tracker.autorun如何选择它的计算?
EN

Stack Overflow用户
提问于 2014-10-14 07:05:50
回答 2查看 2.8K关注 0票数 4

看看Tracker.autorun,我想知道它是如何决定哪些变量将形成计算的依赖关系,这主要是有用的。它只选择“反应性”vars,例如:

代码语言:javascript
复制
  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()块之外。

代码语言:javascript
复制
  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

也许我应该把这作为一个新问题..。这与这个问题有关。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-14 07:55:09

我不是专家,也没读过很多关于它的文章,但我可以试着简单地解释一下。

所有的反应变量都有一个叫做依赖的东西。例如,当创建一个新的ReactiveVar时,就会创建一个新的依赖项。看这里

要从反应性变量中检索值,必须调用一个函数。在"getter“中,依赖项被指示要记住它有依赖项。例如,请看这里 For ReactiveVar.get

若要更改反应性变量的值,必须调用函数。在该"setter“中,依赖项被通知发生了更改,并且指示所有依赖于依赖项的函数都必须重新运行。例如,请看这里 For ReactiveVar.set

不复杂,对吧?好吧,这只是简单的部分,现在剩下的就是建设基础设施,使它工作:)这是更难和更复杂的解释。

反应性变量本身并不是反应性的,它们必须在反应环境中进行评估才能成为反应性变量。通过调用Tracker.autorun创建一个反应性环境。看这里

当调用Tracker.autorun时,传递给它的函数将在新的反应性环境中执行,使用depend方法通知的所有依赖项都将被环境跟踪。当您调用aDependency.depend时,将执行这一功能,它会将依赖项添加到环境列表中,而不是它所依赖的依赖项。

当反应性变量更改其值时,将执行这一功能。它告诉环境它所依赖的一个反应变量已经改变,并使环境中的所有依赖项无效。在此之后,将重新运行传递给Tracker.autorun的整个函数,并跟踪新的依赖项。

你明白大局了吗?它的实现比我所解释的要复杂一些,但我认为这就是它的工作方式。

票数 5
EN

Stack Overflow用户

发布于 2014-10-14 07:46:28

注意,每当您访问一个反应性变量时,它都是通过函数调用来实现的,比如Session.get(...)collection.find(...).fetch()Meteor.status()。像Session.get这样的函数不仅获得会话变量的值,而且还注册了对当前计算的依赖关系(当前计算的范围是动态的,因此Session.get知道它是从自动运行中调用的)。

下面是如何使用Tracker.Dependency实现自己的反应性变量

代码语言:javascript
复制
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

下面是你可以使用的方法:

代码语言:javascript
复制
setCurrentValue("hello")
Tracker.autorun ->
  console.log(getCurrentValue())
# => "hello" printed

setCurrentValue("goodbye") # => "goodbye" printed

要获得更多信息,您可以查看本指南:https://meteor.hackpad.com/DRAFT-Understanding-Deps-aAXG6T9lkf6 (请注意,跟踪器最初在较早版本的Meteor中被称为Dep)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26354582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档