【问题标题】:meteor database latency流星数据库延迟
【发布时间】:2013-01-29 06:33:25
【问题描述】:

我的流星目录由 2 个文件组成:

social.js:

Messages = new Meteor.Collection("messages");

if (Meteor.isServer) {
}

if (Meteor.isClient) {
    Template.temple.messages = function() {
        return Messages.find();  
    };

    Meteor.startup(function () {
            console.log('console startup: ' + Messages.find().count());
    });

    console.log('console normal: ' + Messages.find().count());

    var ali = function() {
        console.log('console normal: ' + Messages.find().count());
    };

    setTimeout(function() {
        console.log('console normal: ' + Messages.find().count());
    }, 2000);
    // The callback function is not called on the following line:
    Meteor.subscribe('messages',function(){alert('ALERT!');});
}

social.html:

<head>
<title>naber</title>
</head>

<body>
{{> temple}}
</body>

<template name = "temple">
{{#each messages}}
{{message}} <br />
{{/each}}
</template>

只有经过一段时间后,集合才会完全加载。如果我环绕 setTimeout,我只能看到文档的真实数量。在数据库真正完全可用后,我该怎么做才能确保我的功能能够执行?

【问题讨论】:

    标签: meteor


    【解决方案1】:

    Meteor.subscribe(NAME)Meteor.publish(NAME) 配对。您的代码尝试订阅名为 "messages" 的内容,但您并未发布具有该名称的内容。

    您获取数据的事实表明您正在使用默认的autopublish 包(请参阅.meteor/packages 进行检查),这意味着您不必显式发布或订阅数据。不幸的是,当自动发布的数据准备好(这可能应该修复)时,没有办法获得回调。所以如果你想这样做,你会想要meteor remove autopublish并使用Meteor.publish来发布你想要发布的数据;然后,您实际上可以使用Meteor.subscribe 回调。

    【讨论】:

      【解决方案2】:

      由于 Meteor 中反应性的工作原理,您始终需要针对服务器尚未将数据发送到客户端的位置设计应用程序状态。您可以将此称为“加载”状态。

      Template 声明中,您必须始终检查您所依赖的数据是否可用。如果模板确实依赖于数据,则希望它首先呈现为空,然后在数据到达时进行更新,因为数据是一个反应式数据源。

      对于您自己的函数,最好以这样的方式编写它们,即它们也依赖于反应式数据源,并使用 Meteor.autorun 之类的东西来确保在此类数据源发生变化时重新执行它们。

      始终将页面加载后要运行的代码放在 Meteor.startup 中,否则在执行代码时您甚至可能无法使用 Meteor。

      以下是我将如何重写您的代码:

      Messages = new Meteor.Collection("messages");
      if (Meteor.isClient){
        Meteor.startup(function() {
          // anything you need to do, like subscriptions 
        });
        Template.temple.loading = function() {
          return Messages.find().count === 0 ? "Loading..." : "";
        }
        Template.temple.messages = function() {
          var messages = Messages.find();
          if (messages.count() > 0) return messages;
        }
      }
      
      <template name="messages">
        {{loading}}
        {{#each messages}}
          {{message}}<br>
        {{/messages}}
      </template>
      

      如果您只是在客户端上使用Messages.find(),则实际上不需要Meteor.subscribe 调用消息。

      【讨论】:

      • 我使用了Meteor.autorun 方法。我想我应该尽可能多地使用它。
      【解决方案3】:

      我通常会显示一个加载指示器,直到订阅加载完毕。请参阅此示例:Meteorjs loading message

      从服务器端发布集合:

      if (Meteor.isServer) {
        Meteor.publish("messages", function () {
          return Messages.find(); // everything
        );
      }
      

      【讨论】:

      • 由于某种原因,onComplete 函数没有被调用。我编辑了示例,但它仍然不起作用。您可以在控制台通过Messages.insert({message:'lolmessage'}) 将文档添加到数据库中。
      • 成功了^^。但我认为Meteor.autorun 更适合此类任务。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多