首页 > 解决方案 > 如何知道 Meteor Collection 订阅是否没有改变。[流星+火焰]

问题描述

以下是 UI 上的订阅部分。

Template.AssociateEmp.onCreated(function(){
    this.validEmail = new ReactiveVar('');

    const tpl = this;
    this.autorun(() => {
        var email = this.validEmail.get();
        this.subscribe('GetUnassociatedUser', email, {
            onReady: function () {},
            onError: function () {}
          });
    });
});

有没有办法知道即使动态数据发生了变化(这里validEmail),Meteor Subscription 不受影响并且没有改变它在 UI 上的数据?当订阅数据未更改时,是否有任何标志或触发的东西?

标签: meteormeteor-blaze

解决方案


自动运行、ReactiveVar 和订阅

在您的代码示例中,订阅本身将重新运行服务器的发布函数,因为订阅的输入变量email取决于反应变量validEmail,因此会触发autorun何时validEmail更改。

您可以通过将某些内容记录到出版物中的控制台来轻松地在服务器控制台上进行检查。

如果validEmail保持不变,则没有理由autorun触发(除非有其他反应源可能不会添加到您的代码示例中)。


订阅的数据呢

现在,如果某些事情导致订阅重新运行,并且您想知道集合的数据是否已更改,您可以轻松检查,collection.count()但这可能是有缺陷的。

想象一下,您的出版物被参数化为通过不同的参数包含不同的字段,那么传输到客户端集合的数据将是不同的。

然后,您需要一种方法来检查客户端集合的数据完整性。


使用哈希来验证完整性

一个可能的帮助是使用sha包从数据集中生成hases。

例如,您可以创建整个集合的一个哈希:

// get data
const data = Collection.find().fetch();

// map data to strings
// and reduce to one string
const hashInput = data.map(doc => JSON.stringify(doc) ).reduce((a, b) => a + b);

// generate hash
const collectionHash = SHA256(hashInput);

在 next 之后,onReady您可以生成集合的新哈希并将其与之前的哈希进行比较。如果它们不同,那么某些东西已经改变了。

如果您只想知道数据是否已更改但不会显示哪个文档已更改,这也消除了迭代集合文档的需要。


散列单个文档

散列单个文档可以让您更深入地了解发生了什么变化。为此,您只需要创建集合的哈希映射:

// get data
const data = Collection.find().fetch();

// map data to strings
const hashes = data.map(doc => { _id: doc._id, hash: SHA256( JSON.stringify(doc) ) });

您可以将这些哈希值与文档的_id. 如果新订阅后文档的哈希值不同,您可以假设更改与该文档相关。

一般注意事项

  • 散列是某种昂贵的操作,因此可能难以跟上大型集合的性能
  • 通常你应该设计你的 pub/sub 和 autorun,当输入改变时输出改变
  • 代码是冷写的,因此它可能无法开箱即用。请让我知道是否有任何问题。

推荐阅读