【问题标题】:Meteor observe changes added callback on server fires on all item流星观察更改在所有项目上的服务器上添加了回调
【发布时间】:2016-12-02 19:55:33
【问题描述】:
Tracker.autorun(function() {
  DATA.find().observeChanges({
    added: function(id, doc) {
       console.log(doc);
    }
  });
});

正在服务器上调用此代码。每次流星服务器启动时,added 函数都会为数据库中的每个项目触发。有没有办法让added 回调仅在添加新项目时触发?

【问题讨论】:

    标签: javascript meteor


    【解决方案1】:

    added 将在首次运行observeChanges 时为结果集中的每个文档调用。诀窍是在此初始化期间忽略回调。我对this 问题的回答中有一个扩展示例,但这段代码应该适合你:

    (function() {
      var initializing = true;
      DATA.find().observeChanges({
        added: function(id, doc) {
          if (!initializing) {
            console.log(doc);
          }
        }
      });
      initializing = false;
    })();
    

    请注意,Tracker.autorun 是一个仅限客户端的函数。在服务器上,我认为它只执行一次。

    【讨论】:

    • 这太简单了,我好几天都想不通。谢谢!我多么愚蠢,没有意识到 Deps.autorun 只是客户端。现在我还有一个问题……如果你能解释一下。如果我在一个非常大的集合上运行这个函数并且从不调用停止,现在 Meteor 使用 oplog,它会对我的系统造成严重的负担。
    • @Bads 你想要钩子之前和之后的功能吗? github.com/matb33/meteor-collection-hooks
    • @PeppeL-G 所以你会说使用 after 和 before 钩子比观察变化更好?假设我的用例是每次将文档添加到集合中时,对其进行修改,然后将其添加到另一个集合中。我也只是浏览了整个文档。它看起来与observeChanges 完全一样。有什么区别?
    • @Bads 刚刚提到它作为替代方案。我认为该软件包不适用于游标,因此我认为该解决方案不会具有您在解决方案中提到的内存缺陷(如果存在)。
    • @PeppeL-G。我懂了。谢谢。我将尝试两种解决方案。
    【解决方案2】:

    我为此苦苦挣扎了很长时间。出于某种原因,David 的回答对我不起作用 - 在初始化变量设置为 false 后触发。

    Avi 的这种模式对我来说是成功的:

    var usersLoaded = false;
    Meteor.subscribe("profiles", function () {
        // at this point all new users sent down are legitimately new ones
        usersLoaded = true;
    });
    
    Meteor.users.find().observe({
        added: function(user) {
            if (usersLoaded) {
                console.log("New user created: ", user);
            }
        }
    });
    

    【讨论】:

    • @chaintng profiles 可能是约翰将他的出版物命名为他发布Meteor.users 集合的地方
    【解决方案3】:

    由于是初始化问题,您可以这样做。

    var observerOfMessages = Messages.find({}).observe({
        added: function(doc){
            if(!observerOfMessages) return;
            console.log(doc)
        }
    });
    

    其实这样更优雅。

    【讨论】:

      【解决方案4】:

      为不匹配旧项目的查询提供选择器。如果使用 mongo ObjectID 作为_id,您可以查询_id 大于最新项目的项目:

      const latest = DATA.findOne({}, {sort: {_id: -1}})
      DATA.find({_id: {$gt: latest._id}}).observeChanges({
        added: function() { ... }
      })
      

      或使用createdAt 时间戳:

      const currentTime = new Date()
      DATA.find({createdAt: {$gt: currentTime}}).observeChanges({
        added: function() { ... }
      })
      

      【讨论】:

        【解决方案5】:

        这是解决此问题的另一种方法:

        Meteor.subscribe('messages', function() {
            var messages = Messages.find();
            var msgCount = messages.count();
        
            messages.observe({
                addedAt: function(doc, atIndex) {
                    if(atIndex > (msgCount - 1)) console.log('added');
                }
            });
        });
        

        仅应在现有金额交付后添加的文档触发。重要的是,这会出现在 Meteor.subscribeonReady 回调中,以便 msgCount 会随着您的订阅而改变……例如,如果您正在对订阅进行分页。

        cursor.observe() documentation

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-06-24
          • 1970-01-01
          • 1970-01-01
          • 2023-04-08
          • 1970-01-01
          • 1970-01-01
          • 2014-01-24
          • 1970-01-01
          相关资源
          最近更新 更多