Meteor.call(Meteor.methods)似乎在客户端和服务器上运行 - 导致问题

Mat*_*att 2 javascript meteor

Meteor.call从客户端执行到一个Meteor.methods方法,console.log事实上,它们都在命令提示符和浏览器控制台中登录.

这个问题是它实际上似乎是在客户端执行 - 它无法访问正确的实体.虽然我在命令提示符下没有出现错误,但这是客户端显示的内容:

模拟调用'createInvite'的效果时出现异常Meteor.makeErrorType.errorClass {error:"not-found",原因:"evaluator_invite__entity_not_found",详情:undefined,message:"evaluator_invite__entity_not_found [not-found]",errorType:"Meteor.错误"...}错误:Meteor.methods.createInvite中的evaluateator_invite__entity_not_found [not-found](http:// localhost:3000/lib/collections/invites.js?505cdea882e0f829d521280c2057403ec134b075:38:15)

它实际上是在客户端运行吗?这个错误应该存在吗?

sai*_*unt 5

如果全球定义,预计Meteor方法将在两个环境上运行,这允许一个称为延迟补偿的好功能.

整个延迟补偿概念是偏离主题的,但基本上它意味着模拟客户端服务器实际上会做什么,就像在数据库中直接插入文档来设计流体UX一样.您实际上是在通过消除网络延迟来使客户端体验超响应之前预测服务器行为.

例如,可能是在用户提交后立即在数据库中插入注释.在这种情况下,Meteor方法调用在服务器上执行并且客户端将共享相同的代码.

有时,在设计负责发送电子邮件的方法时,提供仅客户端模拟(或"存根")完全没有意义.

在其他时候,共享代码的某些部分是有意义的,但是您需要访问特定于环境的对象:例如,插入注释的方法可能会Email.send在服务器上使用,以通知作者在其帖子上添加了注释.

Meteor.methods({
  insertComment: function(comment){
    check(comment, [...]);
    if(! this.isSimulation){
      Email.send([...]);
    }
    return Comments.insert(comment);
  }
});
Run Code Online (Sandbox Code Playgroud)

最终,您必须根据方法的行为方式对代码进行不同的构造.

  • 对于仅服务器方法,在server目录下定义它们,没有客户端对应方法.

  • 对于可以在两个环境上共享完全相同代码的共享方法,只需全局定义它们即可.

  • 对于略有不同的共享方法,您可以使用Meteor.isClient/ Meteor.isServer或method only属性isSimulation来检查当前环境并相应地执行特定代码.

  • 对于几乎没有代码共享的共享方法,我个人使用一种模式,我在客户端和服务器环境中定义Meteor方法并处理共享行为,如检查参数有效性,然后我调用一个负责实际实现正确行为的函数.

lib/method.js

Meteor.method({
  method: function(args){
    check(args, [...]);
    //
    return implementation(args);
  }
});
Run Code Online (Sandbox Code Playgroud)

诀窍是implementation在客户端和服务器上单独定义,根据上下文,将调用正确的函数.

client/method.js

implementation = function(args){
  // define your client simulation / stub
};
Run Code Online (Sandbox Code Playgroud)

server/method.js

implementation = function(args){
  // define your server implementation
};
Run Code Online (Sandbox Code Playgroud)