【问题标题】:Inifinite loop when using Meteor.call inside helper在 helper 中使用 Meteor.call 时的无限循环
【发布时间】:2015-07-22 07:10:00
【问题描述】:

我花了很多时间在我的流星应用上,现在用户进来了,它太慢了!几乎无法使用,尤其是在移动设备上。

我不得不修改我的所有代码并尝试将所有逻辑传递给服务器,这样客户端就不会那么过载。

但是,我遇到了很多问题。我尝试了各种解决方案,但没有任何效果。

无论如何,这里是手头的问题。当我尝试使用服务器端方法时,会触发一个无限循环,该循环将在服务器上进行数千次 console.log。

这里是代码

关于模板/question.js

Template.questionItem.helpers({
      editPermission: function(){
        var question = this
        Meteor.call('checkForEditPermission', question, function(error, result){
          console.log(result)
          Session.set('editPermissionVar', result)
        });
        return Session.get('editPermissionVar')
      }
  });

在服务器/question.js 上

  if (Meteor.isServer) {
  Meteor.startup(function() {
    Meteor.methods({
      checkForEditPermission: function(question) {
        if (Meteor.user() && (question.user_id == Meteor.userId())) {
          return true
        }
      }
    });
  });
}

这是一个非常简单的助手。我有许多其他更复杂的助手,但我不知道如何将它们放在服务器端。我被教导要在客户端上做事,从来没有意识到我正在超载它。

不确定这是否有帮助,但我之前拥有的(仅客户端助手)要简单得多:

editPermission: function(){
    if (currentUser && (this.user_id == currentUser._id)) {
      return true
    }
  }

不需要meteor.call。

问题是,您如何处理来自客户端的调用方法并将它们用作帮助程序。我尝试了很多东西,比如反应式变量和会话变量,但似乎没有任何效果。我知道这个特定的例子非常简单,不需要太多的计算,但我认为更复杂的助手的原理是一样的。问题是如何将它们移动到服务器。

谢谢

【问题讨论】:

  • 您正在导致无限循环,因为该方法每次获得结果时都会重新运行。您可以尝试我的包来避免这种特殊情况下的问题:atmospherejs.com/simple/reactive-method
  • 谢谢!我正在测试这个实现,似乎做得很好。未来的更新会发生什么?这有一天会停止工作吗?我会非常依赖这个,所以我不确定这是否是一个坏主意。
  • 客户端上运行缓慢的 Meteor 应用程序通常指向客户端代码中的错误(例如@stubailo 提到的无限循环)或服务器过载。尝试使用 FF 或 Chrome js 分析器分析客户端代码,以查看所有时间都花在了哪里。您将代码移至服务器的努力不仅会被浪费,还会给您带来服务器端的可伸缩性问题。 Meteor(和 Node)的部分前提是将逻辑移动到客户端,从那时起,您就可以为每个客户端添加计算能力。

标签: javascript methods meteor meteor-helper


【解决方案1】:

问题是,你如何处理调用方法

我的处理方式是 Meteor.call,它在数据库中进行更改并仅使用光标显示数据。

例如,您有一些模板,例如:

Template.exammple.events({'click .sth' : function(event){
    Meteor.call("serveside", {some: data});
    return false;
});

在“服务器端”中,我得到了所有调用或数据库查询/插入/更新等

和助手:

Template.example.helpers({
    example : function(){
    return dbCollectionName.find();
    });

通过这种方式,我不需要使用 Meteor.call 来提取数据/结果。大多数情况下,我将结果保存为其原始形状,并在使用光标将其拉出后添加调整显示。 MongoDB 与流星完美配合,如果你需要一些聚合,你可以使用这个扩展:Meteor Aggregate

【讨论】:

  • 感谢您的回答。我正在对游标进行一些研究,以了解您的解决方案将如何工作。我仍在努力理解的部分是您在哪里声明变量(在您的示例中)dbCollectionName,以便您可以使用光标操作它?我正在尝试使用 Meteor.users 集合,因此我不能简单地声明一个新集合。能告诉我如何获取这个变量,以便它对所有助手和事件都是全局的吗?我只是重新声明收藏吗?我敢肯定它非常简单,我只是想念它,但真的很感激。
猜你喜欢
  • 1970-01-01
  • 2021-09-24
  • 2017-04-25
  • 1970-01-01
  • 2014-03-01
  • 2020-01-31
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多