Meteor.publish() 在 defer 回调中抛出异常

问题描述 投票:0回答:2

我在服务器控制台中发现了这个错误:

延迟回调中出现异常:TypeError: undefined is not a function 在包/ddp/livedata_server.js:1054:1 at Array.forEach(本机) 在 Function..each..forEach (packages/underscore/underscore.js:105:1) 在 [对象对象]._.extend._callStopCallbacks (packages/ddp/livedata_server.js:1053:1) 在 [对象对象]._.extend._deactivate (packages/ddp/livedata_server.js:1043:1) 在包/ddp/livedata_server.js:803:1 在 Function..each..forEach (packages/underscore/underscore.js:113:1) 在 [对象对象]._.extend._deactivateAllSubscriptions (packages/ddp/livedata_server.js:802:1) 在包/ddp/livedata_server.js:444:1 在 [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)

这是我使用的代码:

/* Source: http://phucnguyen.info/blog/how-to-publish-to-a-client-only-collection-in-meteor/ */
var subs = {};
Meteor.publish(

// THROW AN 'EXCEPTION IN DERFER CALLBACK: ...'
  'helperPublication',  
  function () {
    var subscription = this;
    subs[subscription._session.id] = subscription;
    Datasets.find().map(function (dataset) {
      subscription.added(
        'subdatasets',
        dataset._id,
        {
          name: dataset.name,
          data: [],   // To avoid "Uncaught TypeError: Cannot read property 'length' of undefined" error on load
          peaks: []   // Idem
        }
      )
    });
    subscription.onStop();
    subscription.ready()
});

您可以在以下Meteorpad中找到整个应用程序:http://meteorpad.com/pad/6NDneym2qEW7pF9JM/ClearChrom

meteor
2个回答
1
投票

好的,有了这些信息;我认为最好的方法是为此单独收集

data
。因为这样您就可以轻松更改应显示的数据量。该集合的出版物可能如下所示:

Meteor.publish('data', function publishData (limit) {
  return DataCollection.find({}, {
    fields: {
      name: 1,
      data: 1,
      peaks: 1
    },
    limit: limit
  })
});

请注意,发布的回调需要一个参数

limit
。您现在可以像这样订阅它:

Meteor.subscribe('data', 3)

每当您需要更多数据时,您可以:

Meteor.subscribe('data', 6)

所以这个解决方案是反应性的并且非常干净(至少在我看来)。

我还检查了你现有的脚本:

var subs = {};

Meteor.publish(
  'helperPublication',
  function (limit) {
    var subscription = this;
    subs[subscription._session.id] = subscription;
    // I'd use forEach here, because you're not modifying the document
    Datasets.find().forEach(function (doc) {
      subscription.added(
        'subdatasets',
        doc._id,
        {
          name: doc.name,
          // Whith the slice function you can get a subset of the data array
          data: doc.data.slice(0, limit),
          peaks: doc.peaks
        }
      )
    });
    // Calling `subscription.onStop` without an argument doesn't do anything
    // Except maybe through an error
    subscription.onStop(function () {
      // clean the subscription from subs again
      delete subs[subscription._session.id];
    });
    // This shouldn't be necessary.
    // subscription.ready()
});

这仍然存在一些问题。一方面,我建议您尝试避免前面带有下划线的流星属性。 它们可能会在未来的版本中被删除或更改


0
投票

我用不同的方法解决了这个问题。 Meteor 文档中有一个方法 - Meteor.bindEnvironment

      const _this = this;
            Meteor.defer(Meteor.bindEnvironment(() => {
          // Your Code here
      }, () => {}, _this));

我认为它在某种程度上失去了 Meteor.defer 中的 this 的上下文。上面的代码提供了该上下文。这样我就解决了我的问题

© www.soinside.com 2019 - 2024. All rights reserved.