Meteor.methods返回undefined

jag*_*ggy 31 meteor

我正在使用流星0.6.4.

Meteor.methods({
  random: function(top){
    var random = Math.floor((Math.random()*(top+1)));
    return random;
  }
});
Run Code Online (Sandbox Code Playgroud)

每当我执行时它返回undefined

Meteor.call('random', 10);
Run Code Online (Sandbox Code Playgroud)

我有什么想法可以超越这个?

sai*_*unt 61

这是完全正常的行为:Meteor中的服务器方法调用被记录为异步:

在客户端上,如果您没有传递回调并且您不在存根中,则调用将返回undefined,并且您将无法获取该方法的返回值.

这意味着当您要求Meteor.call在服务器上远程执行方法时,本地方法调用是非阻塞的并undefined立即返回.在服务器上调用该方法后,它会将结果异步发送到客户端,因此您应该使用回调模式检索它:

Meteor.call("myMethod", arguments..., function(error, result){
  if(error){
    console.log(error.reason);
    return;
  }
  // do something with result
});
Run Code Online (Sandbox Code Playgroud)

一旦将服务器方法结果发送回客户端,就会在客户端上调用匿名回调函数.

Meteor中还有另一个微妙的功能使我刚才所说的无效:延迟补偿和方法存根.如果服务器方法调用可以在客户端中正确模拟并因此立即执行而无需往返服务器,则可以定义所谓的方法存根(或模拟).

这种行为的一个常见用例是在本地(客户端复制子集)数据库中立即插入一些刚发布的用户内容(例如博客文章下的评论):所有必要的数据和逻辑都可用,模拟是有意义的服务器端插入.接下来发生的事情是,即使服务器尚未确认这些更改,用户也会在提交内容后立即更新网页.(这是一个如何在Meteor中实现延迟补偿的示例).

当然,服务器对最终插入数据库的内容有最后的说法,这意味着当执行服务器端双方法时,其操作将优先并替换在本地数据库中插入的内容.

要定义此类方法存根,您只需在客户端代码上定义相同的服务器方法名称.如果方法声明在共享代码中定义(同时发送到客户端和服务器),则可以通过检查isSimulation属性来测试方法调用是否实际上是模拟:

Meteor.methods({
    myMethod: function(arguments...){
        if(this.isSimulation){
            // called from the client
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

更新26/11/2014:@ steph643评论了我之前答案的最后部分是如何实际错误的,这是一个更正.

请注意,在服务器上,方法调用始终可以使用同步语法调用,因为服务器环境提供了足够的阻塞机制(光纤).

但是,在客户端上,如果从方法存根中返回一些内容,只有当您在另一个存根中时才可以同步执行,并且可以以同步方式检索结果,即

Meteor.methods({
  intermediateMethod: function(){
    return " WORLD";
  },
  method: function(){
    var result = "HELLO";
    result += intermediateResult;
    var intermediateResult = Meteor.call("intermediateMethod");
    return result;
  }
});
Run Code Online (Sandbox Code Playgroud)

考虑到Mongo集合操作(​​插入/更新/删除)是作为Meteor方法实现的,并且它们的客户端版本正在实现可以同步执行的有效存根(minimongo复制的本地数据库子集的修改),这种行为有点奇怪.

  • "如果你从方法存根中返回一些内容,它可以在客户端上同步执行,你可以用通常的方式检索结果".这不是真的.从客户端发出的方法调用返回'undefined'是否存在存根.参看 doc:"在客户端,如果你没有传递一个回调,而你不在存根中[意思是你没有从另一个存根中调用该方法],调用将返回undefined,你将无法得到方法的返回值".无论是否将存根附加到方法,这都适用. (2认同)