Skip to content

跟踪器

¥Tracker

Meteor 有一个简单的依赖跟踪系统,允许它在 Session 变量、数据库查询和其他数据源发生变化时自动重新运行模板和其他计算。

¥Meteor has a simple dependency tracking system which allows it to automatically rerun templates and other computations whenever Session variables, database queries, and other data sources change.

与大多数其他系统不同,你不必手动声明这些依赖和 "正常工作"。该机制简单高效。当你调用支持反应式更新的函数(例如数据库查询)时,它会自动保存当前的 Computation 对象(如果有)(例如,表示当前正在渲染的模板)。稍后,当数据发生变化时,该函数可以 "invalidate" 计算,从而导致其重新运行(重新渲染模板)。

¥Unlike most other systems, you don't have to manually declare these dependencies & it "just works". The mechanism is simple and efficient. When you call a function that supports reactive updates (such as a database query), it automatically saves the current Computation object, if any (representing, for example, the current template being rendered). Later, when the data changes, the function can "invalidate" the Computation, causing it to rerun (rerendering the template).

应用会发现 Tracker.autorun 很有用,而更高级的功能(例如 Tracker.DependencyonInvalidate 回调)主要用于实现新反应数据源的包作者。

¥Applications will find Tracker.autorun useful, while more advanced facilities such as Tracker.Dependency and onInvalidate callbacks are intended primarily for package authors implementing new reactive data sources.

Tracker.autorun

Client only

Summary:

Run a function now and rerun it later whenever its dependencies change. Returns a Computation object that can be used to stop or observe the rerunning.

Arguments:

Source code
NameTypeDescriptionRequired
runFuncTracker.ComputationFunction

The function to run. It receives one argument: the Computation object that will be returned.

Yes
optionsObjectNo

Options:

NameTypeDescriptionRequired
onErrorfunction

Optional. The function to run when an error happens in the Computation. The only argument it receives is the Error thrown. Defaults to the error being logged to the console.

No

Tracker.autorun 允许你运行依赖于反应数据源的函数,这样如果稍后数据发生变化,该函数将重新运行。

¥Tracker.autorun allows you to run a function that depends on reactive data sources, in such a way that if there are changes to the data later, the function will be rerun.

例如,你可以监视游标(即反应数据源)并将其聚合到会话变量中:

¥For example, you can monitor a cursor (which is a reactive data source) and aggregate it into a session variable:

js
Tracker.autorun(() => {
  const oldest = _.max(Monkeys.find().fetch(), (monkey) => {
    return monkey.age;
  });

  if (oldest) {
    Session.set('oldest', oldest.name);
  }
});

或者你可以等待会话变量具有某个值,并在第一次执行时执行某些操作,在计算时调用 stop 以防止进一步重新运行:

¥Or you can wait for a session variable to have a certain value, and do something the first time it does, calling stop on the computation to prevent further rerunning:

js
Tracker.autorun((computation) => {
  if (!Session.equals('shouldAlert', true)) {
    return;
  }

  computation.stop();
  alert('Oh no!');
});

该函数被立即调用,此时如果 shouldAlert 已经为真,它可能会立即发出警报并停止。如果不是,则当 shouldAlert 变为 true 时再次运行该函数。

¥The function is invoked immediately, at which point it may alert and stop right away if shouldAlert is already true. If not, the function is run again when shouldAlert becomes true.

对数据依赖的更改不会导致立即重新运行,而是 "invalidates" 计算,导致它在下次刷新时重新运行。如果有无效的计算,系统空闲时将自动刷新。你还可以使用 Tracker.flush 立即刷新所有待处理的重新运行。

¥A change to a data dependency does not cause an immediate rerun, but rather "invalidates" the computation, causing it to rerun the next time a flush occurs. A flush will occur automatically as soon as the system is idle if there are invalidated computations. You can also use Tracker.flush to cause an immediate flush of all pending reruns.

如果嵌套对 Tracker.autorun 的调用,则当外部调用停止或重新运行时,内部调用将自动停止。当用作重新运行的计算的一部分时,订阅和观察者也会自动停止,从而允许建立新的订阅和观察者。有关订阅和反应性的更多信息,请参阅 Meteor.subscribe

¥If you nest calls to Tracker.autorun, then when the outer call stops or reruns, the inner call will stop automatically. Subscriptions and observers are also automatically stopped when used as part of a computation that is rerun, allowing new ones to be established. See Meteor.subscribe for more information about subscriptions and reactivity.

如果自动运行的初始运行引发异常,则计算将自动停止并且不会重新运行。

¥If the initial run of an autorun throws an exception, the computation is automatically stopped and won't be rerun.

Tracker.autorun 和异步回调

¥Tracker.autorun and async callbacks

Tracker.autorun 可以接受 async 回调函数。要保留异步回调函数内反应变量的反应性,你必须使用 Tracker.withComputation 调用,如下所述:

¥Tracker.autorun can accept an async callback function. To preserve reactivity for the reactive variables inside the async callback function, you must use a Tracker.withComputation call as described below:

Tracker.withComputation

Summary:

Helper function to make the tracker work with promises.

Arguments:

Source code
NameTypeDescriptionRequired
computationcomputation

Computation that tracked

Yes
funcfunc

async function that needs to be called and be reactive

Yes
js
import { Tracker } from "meteor/tracker";


const result = Tracker.withComputation();
  Computation,
() => {},
);
javascript
Tracker.autorun(async function example1(computation) {
  // Code before the first await will stay reactive.
  reactiveVar1.get(); // This will trigger a rerun.

  let links = await LinksCollection.findAsync({}).fetch(); // First async call will stay reactive.

  // Code after the first await looses Tracker.currentComputation: no reactivity.
  reactiveVar2.get(); // This won't trigger a rerun.

  // You can bring back reactivity with the Tracker.withCompuation wrapper:
  let users = await Tracker.withComputation(computation, () => Meteor.users.findAsync({}).fetch());

  // Code below will again not be reactive, so you will need another Tracker.withComputation.
  const value = Tracker.withComputation(computation, () => reactiveVar3.get()); // This will trigger a rerun.
});

根据经验,你可以将所有反应语句封装在 Tracker.withComputation 中以保留当前计算。但这会降低性能 - 它应该只在需要时使用。

¥As a rule of thumb, you are okay with wrapping all reactive statements inside a Tracker.withComputation to preserve current computation. But it comes at a performance cost - it should be used only where needed.

背后的原因是,await 在 Promise 解析函数中隐式地 "moves" 了下面的代码。当此函数运行时(从微任务队列中获取后),Tracker.withComputation 保留对 Tracker.autorun 计算的引用。

¥Reason behind is, that an await implicitly "moves" the code below in a Promise resolved function. When this function runs (after it has been fetched from the micro task queue), Tracker.withComputation preserves the reference to the computation of the Tracker.autorun.

react-meteor-data 包使用 Tracker.withComputation 使 useTracker 接受异步回调。更多信息可见 此处

¥The react-meteor-data package uses Tracker.withComputation to make the useTracker accept async callbacks. More can be seen here

在 2.10 之前的 Meteor 版本中使用异步回调

¥Using async callbacks in versions of Meteor prior to 2.10

Tracker.autorun 可以接受 async 回调函数。但是,异步回调函数将仅依赖于在返回 promise 的任何调用函数之前调用的反应函数。

¥Tracker.autorun can accept an async callback function. However, the async call back function will only be dependent on reactive functions called prior to any called functions that return a promise.

示例 1 - autorun example1() 不依赖于对 Meteor.users 集合的反应性更改。由于它不依赖于任何反应,因此它只会运行一次:

¥Example 1 - autorun example1() is not dependent on reactive changes to the Meteor.users collection. Because it is dependent on nothing reactive it will run only once:

javascript
  Tracker.autorun(async function example1() {
    let asyncData = await asyncDataFunction();
    let users = Meteor.users.find({}).fetch();
  });

但是,只需更改顺序,以便在对 Meteor.users.find 的反应式调用之前没有 async 调用,就会使异步自动运行 example2() 依赖于对 Meteor.users 集合的反应式更改。

¥However, simply changing the order so there are no async calls prior to the reactive call to Meteor.users.find, will make the async autorun example2() dependent on reactive changes to the Meteor.users collection.

示例 2 - autorun example2() 依赖于对 Meteor.users 集合的反应性更改。对 Meteor.users 集合的更改将导致重新运行 example2()

¥Example 2 - autorun example2() is dependent on reactive changes to the Meteor.users collection. Changes to the Meteor.users collection will cause a rerun of example2():

javascript
  Tracker.autorun(async function example2()  {
    let users = Meteor.users.find({}).fetch();
    let asyncData = await asyncDataFunction();
  });

Tracker.flush

Client only

Summary:

Process all reactive updates immediately and ensure that all invalidated computations are rerun.

js
import { Tracker } from "meteor/tracker";


const result = Tracker.flush();

通常,当你进行更改(如写入数据库)时,其影响(如更新 DOM)会延迟,直到系统空闲为止。这让事情变得可预测 - 你可以知道 DOM 不会在代码运行时从你的代码下方发生变化。这也是使 Meteor 运行速度快的原因之一。

¥Normally, when you make changes (like writing to the database), their impact (like updating the DOM) is delayed until the system is idle. This keeps things predictable — you can know that the DOM won't go changing out from under your code as it runs. It's also one of the things that makes Meteor fast.

Tracker.flush 强制完成所有待处理的反应式更新。例如,如果事件处理程序更改了 Session 变量,这将导致部分用户界面重新渲染,则处理程序可以调用 flush 立即执行重新渲染,然后访问生成的 DOM。

¥Tracker.flush forces all of the pending reactive updates to complete. For example, if an event handler changes a Session variable that will cause part of the user interface to rerender, the handler can call flush to perform the rerender immediately and then access the resulting DOM.

每当系统空闲时都会自动刷新,其执行​​的工作与 Tracker.flush 完全相同。刷新过程包括重新运行任何无效的计算。如果在刷新时发生其他无效情况,则它们将作为同一刷新的一部分进行处理,直到没有更多工作要做。在处理未完成的无效操作后,将调用使用 Tracker.afterFlush 注册的回调。

¥An automatic flush occurs whenever the system is idle which performs exactly the same work as Tracker.flush. The flushing process consists of rerunning any invalidated computations. If additional invalidations happen while flushing, they are processed as part of the same flush until there is no more work to be done. Callbacks registered with Tracker.afterFlush are called after processing outstanding invalidations.

flush 内部或正在运行的计算中调用 flush 是非法的。

¥It is illegal to call flush from inside a flush or from a running computation.

Tracker 手册 描述了刷新周期的动机以及 Tracker.flushTracker.afterFlush 做出的保证。

¥The Tracker manual describes the motivation for the flush cycle and the guarantees made by Tracker.flush and Tracker.afterFlush.

Tracker.nonreactive

Client only

Summary:

Run a function without tracking dependencies.

Arguments:

Source code
NameTypeDescriptionRequired
funcfunction

A function to call immediately.

Yes
js
import { Tracker } from "meteor/tracker";


const result = Tracker.nonreactive();
  () => {}
);

调用 func,将 Tracker.currentComputation 临时设置为 null,并返回 func 自己的返回值。如果 func 访问反应性数据源,这些数据源将永远不会导致重新运行封闭计算。

¥Calls func with Tracker.currentComputation temporarily set to null and returns func's own return value. If func accesses reactive data sources, these data sources will never cause a rerun of the enclosing computation.

Tracker.active

Client only

Summary:

True if there is a current computation, meaning that dependencies on reactive data sources will be tracked and potentially cause the current computation to be rerun.

js
import { Tracker } from 'meteor/tracker';

/** @type {Boolean} */
if (Tracker.active) {
  // do something
}

此值对于数据源实现很有用,可确定它们是否被被动访问。

¥This value is useful for data source implementations to determine whether they are being accessed reactively or not.

Tracker.inFlush

Client only

Summary:

True if we are computing a computation now, either first time or recompute. This matches Tracker.active unless we are inside Tracker.nonreactive, which nullfies currentComputation even though an enclosing computation may still be running.

js
import { Tracker } from "meteor/tracker";

/** @returns Boolean */
const result = Tracker.inFlush();

此值表示刷新是否正在进行中。

¥This value indicates, whether a flush is in progress or not.

Tracker.currentComputation

Client only

Summary:

The current computation, or null if there isn't one. The current computation is the Tracker.Computation object created by the innermost active call to Tracker.autorun, and it's the computation that gains dependencies when reactive data sources are accessed.

很少需要直接访问 currentComputation。当前计算由 Tracker.active(测试是否存在)、dependency.depend()(注册它依赖于依赖)和 Tracker.onInvalidate(向其注册回调)隐式使用。

¥It's very rare to need to access currentComputation directly. The current computation is used implicitly by Tracker.active (which tests whether there is one), dependency.depend() (which registers that it depends on a dependency), and Tracker.onInvalidate (which registers a callback with it).

Tracker.onInvalidate

Client only

Summary:

Registers a new onInvalidate callback on the current computation (which must exist), to be called immediately when the current computation is invalidated or stopped.

Arguments:

Source code
NameTypeDescriptionRequired
callbackfunction

A callback function that will be invoked as func(c), where c is the computation on which the callback is registered.

Yes
js
import { Tracker } from "meteor/tracker";


const result = Tracker.onInvalidate();
  () => {}
);

有关更多详细信息,请参阅 computation.onInvalidate

¥See computation.onInvalidate for more details.

Tracker.afterFlush

Client only

Summary:

Schedules a function to be called during the next flush, or later in the current flush if one is in progress, after all invalidated computations have been rerun. The function will be run once and not on subsequent flushes unless afterFlush is called again.

Arguments:

Source code
NameTypeDescriptionRequired
callbackfunction

A function to call at flush time.

Yes
js
import { Tracker } from "meteor/tracker";


const result = Tracker.afterFlush();
  () => {}
);

保证通过多次调用 afterFlush 调度的函数按照调用 afterFlush 的顺序运行。保证在没有需要重新运行的无效计算时调用函数。这意味着如果 afterFlush 函数使计算无效,则在调用任何其他 afterFlush 函数之前将重新运行该计算。

¥Functions scheduled by multiple calls to afterFlush are guaranteed to run in the order that afterFlush was called. Functions are guaranteed to be called at a time when there are no invalidated computations that need rerunning. This means that if an afterFlush function invalidates a computation, that computation will be rerun before any other afterFlush functions are called.

Tracker.Computation {#tracker_computation}

计算对象表示响应反应数据变化而重复运行的代码。计算没有返回值;它们只是执行操作,例如在屏幕上重新渲染模板。使用 Tracker.autorun 创建计算。使用 stop 防止进一步重新运行计算。

¥A Computation object represents code that is repeatedly rerun in response to reactive data changes. Computations don't have return values; they just perform actions, such as rerendering a template on the screen. Computations are created using Tracker.autorun. Use stop to prevent further rerunning of a computation.

每次计算运行时,它都可以访问作为计算输入的各种响应数据源,这些数据源称为其依赖。在未来的某个时间,这些依赖之一可能会通过使其无效来触发重新运行计算。发生这种情况时,依赖将被清除,并且计算将安排在刷新时重新运行。

¥Each time a computation runs, it may access various reactive data sources that serve as inputs to the computation, which are called its dependencies. At some future time, one of these dependencies may trigger the computation to be rerun by invalidating it. When this happens, the dependencies are cleared, and the computation is scheduled to be rerun at flush time.

当前计算(Tracker.currentComputation)是当前正在运行或重新运行(计算)的计算,以及在访问反应数据源时获得依赖的计算。数据源负责使用 Tracker.Dependency 对象跟踪这些依赖。

¥The current computation (Tracker.currentComputation) is the computation that is currently being run or rerun (computed), and the one that gains a dependency when a reactive data source is accessed. Data sources are responsible for tracking these dependencies using Tracker.Dependency objects.

使计算无效会将其 invalidated 属性设置为 true,并立即调用所有计算的 onInvalidate 回调。当发生刷新时,如果计算已失效且未停止,则通过将 invalidated 属性设置为 false 并调用传递给 Tracker.autorun 的原始函数来重新运行计算。当前代码运行完毕时将发生刷新,如果调用 Tracker.flush,刷新将更早发生。

¥Invalidating a computation sets its invalidated property to true and immediately calls all of the computation's onInvalidate callbacks. When a flush occurs, if the computation has been invalidated and not stopped, then the computation is rerun by setting the invalidated property to false and calling the original function that was passed to Tracker.autorun. A flush will occur when the current code finishes running, or sooner if Tracker.flush is called.

停止计算会使其失效(如果有效)以便调用回调,但确保永远不会重新运行。

¥Stopping a computation invalidates it (if it is valid) for the purpose of calling callbacks, but ensures that it will never be rerun.

示例:

¥Example:

js
// If we're in a computation, then perform some clean-up when the current
// computation is invalidated (rerun or stopped).
if (Tracker.active) {
  Tracker.onInvalidate(() => {
    x.destroy();
    y.finalize();
  });
}

computation.stop

Client only

Summary:

Prevents this computation from rerunning.

js

// computation is an instance of Tracker.Computation

const result = computation.stop();

停止计算是不可逆的,并保证永远不会重新运行。你可以随时停止计算,包括从计算自己的运行函数中停止计算。停止已停止的计算没有任何效果。

¥Stopping a computation is irreversible and guarantees that it will never be rerun. You can stop a computation at any time, including from the computation's own run function. Stopping a computation that is already stopped has no effect.

如果计算当前未失效,则停止计算会导致其 onInvalidate 回调立即运行,其 stop 回调也是如此。

¥Stopping a computation causes its onInvalidate callbacks to run immediately if it is not currently invalidated, as well as its stop callbacks.

当重新运行嵌套计算时,嵌套计算会自动停止。

¥Nested computations are stopped automatically when their enclosing computation is rerun.

computation.invalidate

Client only

Summary:

Invalidates this computation so that it will be rerun.

js

// computation is an instance of Tracker.Computation

const result = computation.invalidate();

使计算无效会将其标记为在 刷新时间 重新运行,此时计算再次有效。很少需要手动使计算无效,因为反应式数据源在更改时会使调用计算无效。反应式数据源依次使用一个或多个 Tracker.Dependency 对象执行此无效化。

¥Invalidating a computation marks it to be rerun at flush time, at which point the computation becomes valid again. It is rare to invalidate a computation manually, because reactive data sources invalidate their calling computations when they change. Reactive data sources in turn perform this invalidation using one or more Tracker.Dependency objects.

使计算无效会立即调用在其上注册的所有 onInvalidate 回调。使当前无效或已停止的计算无效不会产生任何影响。计算可以使其自身无效,但如果无限期地继续这样做,结果将是一个无限循环。

¥Invalidating a computation immediately calls all onInvalidate callbacks registered on it. Invalidating a computation that is currently invalidated or is stopped has no effect. A computation can invalidate itself, but if it continues to do so indefinitely, the result will be an infinite loop.

computation.onInvalidate

Client only

Summary:

Registers callback to run when this computation is next invalidated, or runs it immediately if the computation is already invalidated. The callback is run exactly once and not upon future invalidations unless onInvalidate is called again after the computation becomes valid again.

Arguments:

Source code
NameTypeDescriptionRequired
callbackfunction

Function to be called on invalidation. Receives one argument, the computation that was invalidated.

Yes
js

// computation is an instance of Tracker.Computation

const result = computation.onInvalidate();
  () => {}
);

onInvalidate 注册一次性回调,该回调要么立即触发,要么在计算下次无效或停止时立即触发。当计算重新运行或停止时,反应式数据源使用它来清理资源或中断依赖。

¥onInvalidate registers a one-time callback that either fires immediately or as soon as the computation is next invalidated or stopped. It is used by reactive data sources to clean up resources or break dependencies when a computation is rerun or stopped.

要在重新计算后获取回调,你可以从 onInvalidate 调用 Tracker.afterFlush

¥To get a callback after a computation has been recomputed, you can call Tracker.afterFlush from onInvalidate.

computation.onStop

Client only

Summary:

Registers callback to run when this computation is stopped, or runs it immediately if the computation is already stopped. The callback is run after any onInvalidate callbacks.

Arguments:

Source code
NameTypeDescriptionRequired
callbackfunction

Function to be called on stop. Receives one argument, the computation that was stopped.

Yes
js

// computation is an instance of Tracker.Computation

const result = computation.onStop();
  () => {}
);

computation.stopped

Client only

Summary:

True if this computation has been stopped.

computation.invalidated

Client only

Summary:

True if this computation has been invalidated (and not yet rerun), or if it has been stopped.

js
import { Tracker.Computation } from 'meteor/tracker';

/** @type {Boolean} */
if (Tracker.Computation#invalidated) {
  // do something
}

此属性最初为 false。它被 stop()invalidate() 设置为 true。在刷新时重新计算计算时,它会重置为 false。

¥This property is initially false. It is set to true by stop() and invalidate(). It is reset to false when the computation is recomputed at flush time.

computation.firstRun

Client only

Summary:

True during the initial run of the computation at the time Tracker.autorun is called, and false on subsequent reruns and at other times.

js
import { Tracker.Computation } from 'meteor/tracker';

/** @type {Boolean} */
if (Tracker.Computation#firstRun) {
  // do something
}

此属性是一种便利,可支持常见模式,其中计算具有特定于第一次运行的逻辑。

¥This property is a convenience to support the common pattern where a computation has logic specific to the first run.

computation.firstRunPromise

Client only

Summary:

Forces autorun blocks to be executed in synchronous-looking order by storing the value autorun promise thus making it awaitable.

在初始计算完成后,Computation.firstRunPromise 将设置为自动运行函数调用的结果。如果 autorun 函数是异步函数,则它将包含其 promise,从而使执行的完成可等待。这使我们能够像这样手动同步自动运行:

¥Computation.firstRunPromise will be set to the result of the call of the autorun function after the initial computation has been completed. If the autorun function is an async function, it'll then contain its promise, thus making the completion of the execution await-able. That allows us to manually synchronize autoruns like this:

js

await Tracker.autorun(async () => {
  await Meteor.userAsync();
  (...more async code...)
}).firstRunPromise;

await Tracker.autorun(async () => {
  await asyncSomeOrOther();
  (...more async code...)
}).firstRunPromise;

为了获得更好的开发者体验,firstRunPromise 会自动附加到你的异步 autorun 调用中,因此你不必自己编写它们。意味着这也有效:

¥For a better developer experience firstRunPromise is automatically appended to your async autorun calls so you don't have to write them yourself. Meaning this also works:

js

await Tracker.autorun(async () => {
  await Meteor.userAsync();
  (...more async code...)
});

await Tracker.autorun(async () => {
  await asyncSomeOrOther();
  (...more async code...)
});

Tracker.Dependency

依赖表示计算可能依赖的反应数据的原子单位。反应式数据源(例如 Session 或 Minimongo)在内部为不同的数据片段创建不同的依赖对象,每个数据片段可能依赖于多个计算。当数据发生变化时,计算将失效。

¥A Dependency represents an atomic unit of reactive data that a computation might depend on. Reactive data sources such as Session or Minimongo internally create different Dependency objects for different pieces of data, each of which may be depended on by multiple computations. When the data changes, the computations are invalidated.

依赖不存储数据,它们仅跟踪一组计算,以便在发生更改时使其无效。通常,数据值会附带一个依赖对象,用于跟踪依赖于它的计算,如下例所示:

¥Dependencies don't store data, they just track the set of computations to invalidate if something changes. Typically, a data value will be accompanied by a Dependency object that tracks the computations that depend on it, as in this example:

js
let weather = 'sunny';
const weatherDep = new Tracker.Dependency();

function getWeather() {
  weatherDep.depend();
  return weather;
}

function setWeather(newWeather) {
  weather = newWeather;

  // Note: We could add logic here to only call `changed` if the new value is
  // different from the old value.
  weatherDep.changed();
}

此示例使用简单的 getter 和 setter 实现了天气数据源。getter 使用 depend() 记录当前计算依赖于 weatherDep 依赖,而 setter 通过调用 changed() 发出依赖信号以使所有依赖计算无效。

¥This example implements a weather data source with a simple getter and setter. The getter records that the current computation depends on the weatherDep dependency using depend(), while the setter signals the dependency to invalidate all dependent computations by calling changed().

依赖本身不存储数据的原因是将多个依赖与同一段数据关联起来会很有用。例如,一个依赖可能表示数据库查询的结果,而另一个依赖可能仅表示结果中的文档数量。依赖可以表示天气是否晴朗,或者温度是否高于冰点。Session.equals 以这种方式实现以提高效率。调用 Session.equals('weather', 'sunny') 时,当前计算依赖于内部依赖,即使天气从 rainy 变为 cloudy,该依赖也不会改变。

¥The reason Dependencies do not store data themselves is that it can be useful to associate multiple Dependencies with the same piece of data. For example, one Dependency might represent the result of a database query, while another might represent just the number of documents in the result. A Dependency could represent whether the weather is sunny or not, or whether the temperature is above freezing. Session.equals is implemented this way for efficiency. When you call Session.equals('weather', 'sunny'), the current computation is made to depend on an internal Dependency that does not change if the weather goes from, say, rainy to cloudy.

从概念上讲,依赖可以做的唯一两件事是获得依赖和更改。

¥Conceptually, the only two things a Dependency can do are gain a dependent and change.

依赖的依赖计算始终有效(它们具有 invalidated === false)。如果依赖在任何时候失效,无论是由依赖本身还是其他方式,它都会立即被删除。

¥A Dependency's dependent computations are always valid (they have invalidated === false). If a dependent is invalidated at any time, either by the Dependency itself or some other way, it is immediately removed.

查看 Tracker 手册 以了解如何使用 Tracker.Dependency 创建反应式数据源。

¥See the Tracker manual to learn how to create a reactive data source using Tracker.Dependency.

dependency.changed

Client only

Summary:

Invalidate all dependent computations immediately and remove them as dependents.

js

// dependency is an instance of Tracker.Dependency

const result = dependency.changed();

dependency.depend

Client only

Summary:

Declares that the current computation (or fromComputation if given) depends on dependency. The computation will be invalidated the next time dependency changes.

If there is no current computation and depend() is called with no arguments, it does nothing and returns false.

Returns true if the computation is a new dependent of dependency rather than an existing one.

Arguments:

Source code
NameTypeDescriptionRequired
fromComputationTracker.Computation

An optional computation declared to depend on dependency instead of the current computation.

No
js

// dependency is an instance of Tracker.Dependency
/** @returns Boolean */
const result = dependency.depend();
  Computation
);

dependency.depend() 用于反应式数据源实现,以记录从当前计算中访问 dependency 的事实。

¥dependency.depend() is used in reactive data source implementations to record the fact that dependency is being accessed from the current computation.

dependency.hasDependents

Client only

Summary:

True if this Dependency has one or more dependent Computations, which would be invalidated if this Dependency were to change.

js

// dependency is an instance of Tracker.Dependency
/** @returns Boolean */
const result = dependency.hasDependents();

对于创建许多内部依赖的反应数据源,此功能可用于确定特定依赖是否仍在跟踪任何依赖,或者是否可以清理它以节省内存。

¥For reactive data sources that create many internal Dependencies, this function is useful to determine whether a particular Dependency is still tracking any dependency relationships or if it can be cleaned up to save memory.