何时使用Meteor.methods并使用存根

时间:2012-09-01 21:51:26

标签: javascript node.js meteor stubs

使用Meteor,我试图了解何时使用服务器端Meteor.methods(),同时仍保留即时UI更新。

来自Andrew Scala的introductory tutorial,他声称当您想要更新和修改数据库文档时应该使用Meteor.methods()

  

我们的想法是您定义服务器上的所有功能   修改和更新数据等危险的东西,然后让客户端   调用这些函数并获取常规函数之类的返回值。该   客户端永远不会看到实现,也不会亲自修改   数据。服务器完成所有工作。

遵循这个建议,我在我的代码中实现了这个:

服务器端:

Meteor.methods({

  addMovie: function(data) {
    var movie = Movies.insert({name: data});
    return movie;
  },

  ...

客户端:

Template.movies.events = ({

  'click #add-movie': function(e) {

    var name = document.getElementById('movie-name').value;
    Meteor.call('addMovie', name);

    return false;

  }, 

  ...

这很有效,但速度很慢。 UI不会像在客户端调用Movies.insert()时那样立即更新。 docs表示,为了解决问题,您可以在客户端创建存根:

  

在客户端上调用方法定义与之关联的存根函数   同名的服务器方法。您不必为其定义存根   你的方法,如果你不想。在这种情况下,方法调用就是   比如在其他系统中进行远程过程调用,你必须等待   来自服务器的结果。

但这些存根应该是什么样的?它应该与服务器端方法基本相同吗?如果是这样,重点是什么?我正在寻找一个更全面的解释Meteor.methods()的用法和目的,存根的点/用法及其实现。

修改: David Greenspan帮助澄清了meteor-talk上Meteor.methods()和存根的使用。

4 个答案:

答案 0 :(得分:19)

这是另一个例子。

说你正在编写一个宾果游戏而你点击按钮来调用“house!”..在你可能称之为方法的点击事件中,例如。

Method.call("callHouse");

这将调用服务器方法:

// on the server
Meteor.methods({
  callHouse: function () {
    if (currentGame.isInProgress) {
      currentGame.winner = this.userId;
      currentGame.end();
    }
  }
});

如果你是第一个打电话给“house”的人,那么这个方法会把你标记为赢家..但是,让我们假装这个方法非常慢,而你的客户端应用程序正在等待......你肯定99%确定服务器会确认你是胜利者 - 你只想在没有等待的情况下更新用户的屏幕..在这种情况下实现客户端存根:

// on the client
Meteor.methods({
  callHouse: function () {
    currentGame.winner = Meteor.userId();
    // add any other side-effects you expect to occur here
  }
});

当服务器结果返回时,如果返回的数据与您在存根中设置的数据不同,它将更正它并相应地刷新屏幕。

答案 1 :(得分:12)

简而言之:

在推送到服务器的文件中定义一些方法(Meteor.methods),这些方法将在服务器上进行实际工作,在推送到客户端的文件中定义一些方法(Meteor.methods)以获得'瞬间& #39;客户端上的行为(例如加载指示符),直到服务器将结果更改推送回客户端

这是David的原帖:

  

嗨Ben,

     

原则上,一种方法可以对其执行完全不同的动作   客户端和服务器,例如显示加载指示器   客户端并与服务器上的远程API通信。打电话给   客户端上的Meteor.methods定义客户端行为,并调用   服务器上的Meteor.methods定义服务器行为。

     

对于在数据库上运行的方法,通常是相同的   实施将对两者都有效。客户端版本会影响   客户端数据库(浏览器端"缓存"订阅的文档   to)和服务器端版本影响真实数据库。当。。。的时候   客户听到回来,它会快速地回复"到服务器端的结果   突变;客户端数据库突变被丢弃(或   撤消,取决于你如何看待它)。如果是客户端方法   调用其他方法,这些辅助调用远程调用   服务器。服务器端版本将调用相同的方法   是否适合服务器。

     

因此,您提供的任何客户端方法只是一个"模拟"和   并不一定准确(可能无法做到)。希望是   您通常免费获得模拟impl,因为它是   与服务器impl相同!

     

这会回答你的问题吗?

     

- 大卫

答案 2 :(得分:3)

如果您在客户端/服务器共享的文件上定义一个方法,例如/collections,那么两者都可以访问它并自动存根?

所以:

/collections/houses.js

Meteor.methods({
  callHouse: function () {
    if (currentGame.isInProgress) {
      currentGame.winner = this.userId;
      currentGame.end();
    }
  }
});

这将可供客户端和服务器使用。如果它没有通过,服务器将自动拒绝客户端更新/恢复它。

答案 3 :(得分:3)

正如Daniel所说,您可以在文件上定义一个方法,该方法不在客户端或服务器目录中,并且可以在双方都可用。您还可以使用isSimulation布尔值进行其他检查。例如,它可能看起来像这样:

Meteor.methods({
  addMovie: function (movieData) {
    if (!this.isSimulation) {
      check(movieData, someAdditionaCheckinFunc);
    }
    Movies.insert(movieData);
  }
})

因此,条件分支中的代码将仅在服务器上执行。