如何在Meteor.js中的特定模板中实际更新数据库10秒后呈现数据?

时间:2016-10-24 19:35:26

标签: mongodb meteor publish-subscribe meteor-blaze

我正在开发一款名为Bingo的简单游戏。现在我做了一个观看选项,我需要在这个选项中不是实时播放游戏,而是延迟10秒。现在我该如何轻松地做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以使用.observe()。它会告诉您添加/更改事件的时间,并且您可以在这些事件中执行任何操作。文档here

CollectionName.find().observe({
    added: function (document) {
        //do something here, like delaying the update
    },

    changed: function (document) {
        //do something here, like delaying the update
    },
});

答案 1 :(得分:1)

使用observe例程的想法似乎很好,但至少有几种方法可以实现。一种方法是延迟订阅本身。这是一个有效的例子:

import { Meteor } from 'meteor/meteor';
import { TheCollection } from '/imports/collections.js';

Meteor.publish('delayed', function (delay) {
  let isStopped = false;

  const handle = TheCollection.find({}).observeChanges({
    added: (id, fields) => {
      Meteor.setTimeout(() => {
        if (!isStopped) {
          this.added(TheCollection._name, id, fields);
        }
      }, delay);
    },
    changed: (id, fields) => {
      Meteor.setTimeout(() => {
        if (!isStopped) {
          this.changed(TheCollection._name, id, fields);
        }
      }, delay);
    },
    removed: (id) => {
      Meteor.setTimeout(() => {
        if (!isStopped) {
          this.removed(TheCollection._name, id);
        }
      }, delay);
    }
  });

  this.onStop(() => {
    isStopped = true;
    handle.stop();
  });

  this.ready();
});

另一种方法是创建仅用于渲染目的的本地ProxyCollection。使用与订阅案例中相同的“观察技术”,数据将从TheCollection复制到ProxyCollection,并有一些延迟。

在这两种情况下,您都需要处理一些边缘情况,例如:

  1. 数据是否应在初始加载时延迟?
  2. 如果删除文档,是否应延迟更新?
  3. 是否应该为初始化更改的用户延迟更新?
  4. 它们都可以通过利用和调整上述技术来解决。我相信,他们不在这个问题的范围内。

    修改

    为了防止初始数据加载延迟,您可以按如下方式更新上述代码:

    let initializing = true;
    
    const handle = TheCollection.find({}).observeChanges({
      added: (id, fields) => {
        if (initializing) {
          this.added(TheCollection._name, id, fields);
        } else {
          Meteor.setTimeout(() => {
            if (!isStopped) {
              this.added(TheCollection._name, id, fields);
            }
          }, delay);
        }
      },
      // ...
    });
    
    // ...
    
    this.ready();
    initializing = false;
    

    起初,为什么这样做可能并不明显,但这里的所有内容都是在光纤内执行的。 observeChanges例程“阻止”,它首先为整个初始数据集的每个文档调用added。只有这样,它才会进入发布方法体的下一部分。

    人们应该注意的是,由于上述行为,订阅可能会在处理初始数据集之前停止,因此,在定义onStop回调之前。在这种特殊情况下,它不应该受到伤害,但有时它可能会有问题。