8

我有一个带有大量“消息”集合的 MongoDB;属于特定的所有消息groupId。所以从这样的出版物开始:

Meteor.publish("messages", function(groupId) {
  return Messages.find({
    groupId: groupId
  });
});

和这样的订阅:

Deps.autorun(function() {
   return Meteor.subscribe("messages", Session.get("currentGroupId"));
});

这给我带来了麻烦,因为最初currentGroupId是未定义的,但是 sill mongod 会用尽 CPU 来查找消息groupId == null(尽管我知道没有消息)。

现在,我尝试将出版物改写如下:

Meteor.publish("messages", function(groupId) {
  if (groupId) {
    return Messages.find({
      groupId: groupId
    });
  } else {
    return {}; // is this the way to return an empty publication!?
  }
});

和/或将订阅重写为:

Deps.autorun(function() {
   if (Session.get("currentGroupId")) {
     return Meteor.subscribe("messages", Session.get("currentGroupId"));
   } else {
     // can I put a Meteor.unsubscribe("messages") here!?
   }
});

这两者最初都有帮助。但是一旦currentGroupId再次变为未定义(因为用户导航到不同的页面),mongod 仍然忙于重新查询数据库以获取最后一个 subscribed groupId。那么我怎样才能取消订阅一个出版物,以便停止查询 mongod 呢?

4

4 回答 4

9

根据文档,它必须是http://docs.meteor.com/#publish_stop

this.stop() 在发布函数内部调用。停止该客户端的订阅;onError 回调不会在客户端上调用。

所以像

Meteor.publish("messages", function(groupId) {
  if (groupId) {
    return Messages.find({
      groupId: groupId
    });
  } else {
    return this.stop();
  }
});

我猜在客户端你可以像在你的第一个例子中那样删除你的 if/else

Deps.autorun(function() {
   return Meteor.subscribe("messages", Session.get("currentGroupId"));
});
于 2013-05-27T18:02:06.330 回答
7

.stop()我发现调用从调用返回的处理程序上的函数更简单直接.subscribe()

let handler = Meteor.subscribe('items');
...
handler.stop();
于 2016-03-13T17:13:18.950 回答
5

只需在发布中添加一个条件:

Meteor.publish("messages", function(groupId) {
  if (groupId) {
    return Messages.find({
      groupId: groupId
    });
});

并保留订阅:

Deps.autorun(function() {
  return Meteor.subscribe("messages", Session.get("currentGroupId"));
});

做这项工作。

无需明确停止发布。最终,在完成当前运行的查询并发出另一个查询(似乎在系统中的某个地方排队)之后,不再查询 MongoDB。

于 2013-05-28T13:06:10.277 回答
0

在你的情况下,你应该停止autorun

文档中有一个示例

您的自动运行实际上是使用允许您停止它的参数调用的:

Deps.autorun(function (c) {
  if (! Session.equals("shouldAlert", true))
    return;

  c.stop();
  alert("Oh no!");
});
于 2013-05-27T19:06:42.493 回答