【问题标题】:meteorjs stop subscribtion of collection流星js停止订阅收藏
【发布时间】:2014-09-01 06:47:26
【问题描述】:

我想停止订阅过程。

目前这是我的代码:

if (Meteor.isClient) {

    Meteor.autorun(function(){
        var query;
        query = Session.get('search.query');
        if (!query) return;
        if (Envi.temp.searchSubscribtion) {
            console.log('Subscribtion for search has to stop ... ');
            Envi.temp.searchSubscribtion.stop();
        }

        Envi.temp.searchSubscribtion = Meteor.subscribe('search', query, {
            onReady : function () {
                console.log('Finished.');
            }
        });
    });

}

Env 是一个全局函数,我将订阅临时保存在temp.searchSubscribtion 中。

现在的问题:我将search.query 值更改为查询以获取所有项目。大约 1 分钟后显示完成的 console.log “Finished”。

在此之后,我将search.query 更改为一个查询,它只获取一些项目。大约 5 秒后显示 Finished console.log。

如您所见:一个长查询,一个小查询。

我现在想做的是:

当一个查询被改变时,当前的订阅必须被取消并且新的订阅必须开始,但是:

当我设置长查询和右(!)之后,我将 search.query 会话更改为小查询,“完成”console.log 在 1 分钟多后显示。

Envi.temp.searchSubscribtion.stop();”正确执行(我看到控制台日志)但订阅并没有停止 - 似乎服务器刚刚完成第一个订阅而不是完成第二个 - 就像一个队列。

任何想法如何取消正在运行的订阅?

【问题讨论】:

    标签: javascript meteor


    【解决方案1】:

    因为原始查询需要花费时间才能返回,所以运行您的订阅的单个 Fiber 将被停止。在完成之前,您将无法向其发送任何其他订阅命令(停止/新订阅等)。

    你有几个选择:

    1. 加快查询速度(索引?)
    2. 发布所有文档[可能限制某些字段],然后在客户端上搜索。然后,您可以通过发送 _id 列表来订阅完整的字段集
    3. 不要使用发布,而是通过Meteor.methods(非响应式/自动发布)发送数据。
    4. 结合 2 和 3;调用一个流星方法进行查询,它只返回一个_id的列表,然后订阅_id的列表
    5. 除了使用服务器端路由外,请执行 (4),以避免阻塞流星方法(如果您要触发大量方法调用...)

    在使用 Meteor.methods 时要小心,以避免阻塞您需要的光纤:

    1. 来自客户的电话,Meteor.apply('myMethod',[parameter1, parameter2 /* etc */], {wait: false}, callback);
    2. 在服务器调用 this.unblock() 的方法体中。

    (4)的一个例子:

    if (Meteor.isServer) {
      Meteor.methods('search', function (query) {
        this.unblock();
        // some query logic??
        return _.pluck(collection.find(query, {_id: true}).fetch(), '_id');
      });
    
      Meteor.publish('searchResults', function (resultIds) {
        return collection.find({_id: {$in: resultIds}});
      });
    
    }
    if (Meteor.isClient) {
    
      Meteor.autorun(function () {
        var query;
        query = Session.get('search.query');
        if (!query) return;
        Meteor.apply('search', [query], {wait:false}, function (err, resultIds) {
          if (err) {
            console.log('error!', err);
            return;
          }
          var currentSearch = Session.get('search.query');
          if (!EJSON.equals(currentSearch, query)) {
            console.log('Results returned for', query, ' however current search is ', currentSearch);
            return;
          }
    
          if (Envi.temp.searchSubscribtion) {
            console.log('Subscribtion for search has to stop ... ');
            Envi.temp.searchSubscribtion.stop();
    
          }
          Envi.temp.searchSubscribtion = Meteor.subscribe('searchResults', resultIds, {
            onReady: function () {
              console.log('Finished for query:', query);
            }
          });
        });
      });
    
    }
    

    【讨论】:

    • 嘿内森。首先感谢您的回答。但是当我使用你的代码时有一个问题:当调用 Meteor.apply() 方法时,“resultIds”总是返回“null”作为值。但是在我的 Meteor.method (搜索)中使用 console.log 时,结果是一个有效的数组。为了测试,我将洞 msearch-method 代码更改为“return test”,但“resultIds”值始终为“undefined”。
    • 我认为“resultIds”总是未定义,因为“wait:false”。但是当它不是“等待:假”时,该方法不能被取消 - 对吧?
    • 啊不,如果忘记回调的第一个参数是错误,请查看更新代码!
    • 感谢你的诡计,内森。这很有魅力,现在当我在另一个搜索仍在进行中时再次尝试搜索时,它会提高性能。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    • 2016-02-17
    • 2012-10-01
    • 2014-04-27
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    相关资源
    最近更新 更多