【问题标题】:Publish/subscription issue with Meteor 1.2.0.1Meteor 1.2.0.1 的发布/订阅问题
【发布时间】:2015-09-24 18:25:58
【问题描述】:

在 Meteor 应用中,发布到服务器上的集合的数据不会出现在客户端中。

从默认的 Meteor 应用程序开始,我已将默认 JavaScript 文件更改为以下内容:

Test = new Mongo.Collection("test")

if (Meteor.isClient) {
  Meteor.subscribe("test")
  console.log(Test.find({}).fetch())
}

if (Meteor.isServer) {
  Meteor.startup(function () {
    Meteor.publish("test", function () {
      var cursor = Test.find({})
      var result = cursor.fetch()
      console.log(result)
      console.log(JSON.stringify(result))
      return cursor
    })

    var selector = {}
    var modifier = { key: "value" }
    var options = {}
    var callback = function (error, data) {
      console.log("Test", error, data)
    }
    Test.upsert( selector, modifier, options, callback )
  });
}

在服务器终端中,我可以看到一个文档已添加到 Test 集合中,并且该集合现在包含一个文档,但 console.log(Test.find({}).fetch()) 在浏览器中的输出是[]

这是来自服务器的典型输出:

I20150924-14:38:59.313(-4)? Test null { numberAffected: 1 }
=> Meteor server restarted
I20150924-14:38:59.404(-4)? [ { _id: 'e3B6js9xq3pbspego', key: 'value' } ]
I20150924-14:38:59.405(-4)? [{"_id":"e3B6js9xq3pbspego","key":"value"}]

从浏览器:

Navigated to http://localhost:3000/
[]                   mongoTest.js:5 

我错过了什么?

【问题讨论】:

  • 您可以在返回发布结果之前执行console.log(Test.find({}).fetch());console.log(JSON.stringify(Test.find({}).fetch())); 吗? ``` Meteor.publish("test", function () { return Test.find() }) ```
  • @Abhay — 我已经做到了,并更新了我的问题。服务器上的集合中肯定有文档。
  • 能否尝试在启动块中包含客户端逻辑Meteor.startup(function () { \\insert client here }

标签: mongodb meteor publish-subscribe


【解决方案1】:

这是意料之中的,因为subscribe 不会阻止浏览器的执行。订阅开始后,Test.find() 在文档到达客户端之前执行。这是一个应该打印结果的实现:

if (Meteor.isClient) {
  Meteor.subscribe('test', function() {
    console.log(Test.find({}).fetch());
  });
}

更强大的解决方案是使用autorun,因为它通过添加第一个文档来避免任何竞争条件:

var handle = Meteor.subscribe('test');

Tracker.autorun(function() {
  if (handle.ready())
    console.log(Test.find({}).fetch());
});

推荐阅读:common mistakes的“订阅不屏蔽”部分。

【讨论】:

    【解决方案2】:

    在客户端代码中添加Tracker.autorun(...)即可解决问题:

    if (Meteor.isClient) {
      Tracker.autorun(function () {
        Meteor.subscribe("test")
        console.log(Test.find({}).fetch())
      })
    }
    

    现在浏览器控制台的输出是:

    Navigated to http://localhost:3000/
    []                   mongoTest.js:6
    v [Object]           mongoTest.js:6
      > 0: Object
          _id: "e3B6js9xq3pbspego"
          key: "value"
        length: 1
      > __proto__: Array[0]
    

    显然Test.find({}).fetch()在客户端第一次连接服务器时发现了一个空集合,然后服务器有时间更新客户端上的集合。

    【讨论】:

      猜你喜欢
      • 2016-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 2013-11-18
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多