【问题标题】:How can I render data after 10 seconds of actual database update reactively in a particular template in Meteor.js?如何在 Meteor.js 的特定模板中响应式地在实际数据库更新 10 秒后呈现数据?
【发布时间】:2016-10-24 19:35:26
【问题描述】:

我目前正在开发一款名为 Bingo 的简单游戏。现在我做了一个观看选项,我需要在其中播放比赛,而不是实时播放,但有 10 秒的延迟。现在我怎样才能轻松做到这一点?

【问题讨论】:

  • 你检查 Meteor.setTimeout() 了吗?会做我想的工作。 docs.meteor.com/api/timers.html
  • 要向所有玩家广播吗?如果是这样,您将需要类似 synced-cron 包的东西。您可以按 10 秒的时间表更新数据库,客户端可以接收数据库更改

标签: mongodb meteor publish-subscribe meteor-blaze


【解决方案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. 是否应该为初始化更改的用户延迟更新?

它们都可以通过利用和调整上述技术来解决。但我相信,它们不在这个问题的范围内。

编辑

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

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 回调之前。在这种特殊情况下,它不应该受到伤害,但有时可能会出现问题。

【讨论】:

  • 但我不想在初始加载时延迟数据。我该怎么做?
  • @Al-aminNowshad 我已经更新了答案。希望它会有所帮助。
【解决方案2】:

您可以使用.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
    },
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 2017-12-14
    • 2019-05-28
    • 1970-01-01
    • 2012-12-18
    • 2019-10-27
    • 1970-01-01
    相关资源
    最近更新 更多