Meteor 的反应在幕后是如何工作的?

Posted

技术标签:

【中文标题】Meteor 的反应在幕后是如何工作的?【英文标题】:How does Meteor's reactivity work behind the scenes? 【发布时间】:2012-05-02 20:28:04 【问题描述】:

我看了docs,看了source behind reactivity,还是看不懂。

有人能解释一下这是如何在幕后工作的吗,因为这对我来说就像魔法:)。

【问题讨论】:

【参考方案1】:

所以它实际上相当简单,在基本层面上涉及两种类型的功能:

    创建反应式上下文的函数(反应式函数)

    使反应式上下文无效的函数(使函数无效)

    两者兼得的功能。 (我谎称有 3 个)

当您调用reactive function 时,它会创建一个context,该流星在全球范围内存储并且reactive function 订阅invalidation 回调。传递给响应式函数的函数或从其中运行的任何函数可以是 invalidating function,并且可以获取当前的 context 并将其存储在本地。然后,这些函数可以在任何时候(例如在数据库更新或简单的计时器调用中)使 context 无效。原始的reactive function 将接收该事件并重新评估自己。

这是使用流星函数的一步一步(注意Tracker.autorun曾经被称为Deps.autorun):

Tracker.autorun(function() 
  alert("Hello " + Session.get("name"));
);

Session.set("name", "Greg");
    autorun 以函数为参数 在 autorun 运行这个函数之前,它会创建一个context autorun 将回调附加到context 的失效事件 此回调将重新运行传递给 autorun 的函数 然后该函数首次在context 中运行。 Meteor 将此context 全局存储为当前活动的context 函数内部还有另一个函数:Session.get() Session.get() 既是 reactive function 也是 invalidating function Session.get 设置它自己的context 并在内部将其与键“名称”关联 Session.get 从流星全局检索当前上下文(自动运行的上下文) Session.get 注册到它自己的上下文的失效回调,只会使其封闭的上下文(在这种情况下,自动运行的上下文)失效 所以现在我们有 2 个上下文,autorun 和 session.get 的

    当这些函数返回时,meteor 会清理活动上下文全局变量

    Session.set 是另一个能够使context 无效的函数。

    在这种情况下,我们使所有由 Session 创建的与键“名称”关联的contexts 无效 所有contexts 在失效时都会运行它们的失效回调。 那些回调只是使其封闭的contexts 无效(这是 Session.get 的设计,而不是无效回调必须做的) 那些封闭contexts 现在运行他们的失效回调。 在自动运行的情况下,该回调运行我们最初传递给自动运行的函数,然后再次设置context

整个实现实际上也相当简单,您可以在此处查看:https://github.com/meteor/meteor/blob/master/packages/tracker/tracker.js

这里有一个很好的例子来说明它是如何工作的:https://github.com/meteor/meteor/blob/master/packages/reactive-dict/reactive-dict.js

反应式编程实际上并不是特定于流星或 JS 的 你可以在这里阅读:http://en.wikipedia.org/wiki/Reactive_programming

【讨论】:

很好的解释,这应该在流星页面中。 这个视频很有帮助eventedmind.com/posts/meteor-reactivity-with-contexts “自动订阅将函数作为它的参数”中的撇号真的不应该存在! 实现的链接现在无效 @ephemer 谢谢,我已经更新了答案,等待同行评审。

以上是关于Meteor 的反应在幕后是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

Bluemix/CloudFoundry + Meteor - 如何重置项目?

Meteor:在服务器端调试

React/ Flux 前端和 Meteor 后端

Meteor - 安装 android 平台找不到 ANDROID_HOME 变量

找不到模块'./..../x.html' - TsLint / Angular-Meteor

使输入上的 disabled 属性与 Meteor 助手反应的最佳方法是啥?