2013-07-04 60 views
31

我使用meteor 0.6.4。Meteor.methods返回undefined

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

每当我执行

Meteor.call('random', 10); 

任何想法我怎么能得到过去,这则返回undefined?

回答

57

这是一个完全正常的行为:服务器方法调用流星是documented是异步的:

在客户端,如果不传递一个回调,你是不是末节里,调用将返回未定义,你将无法获得方法的返回值。

这意味着,当你问一个Meteor.call方法在服务器上远程执行,调用本地方法是非阻塞,并立即返回undefined。 当方法被调用的服务器上,将异步结果发送给客户端,所以你应该使用回调格局检索:

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

匿名回调函数将在客户端上被称为尽快服务器方法结果被发送回客户端。

流星还有另一个微妙的功能,使我刚刚说的无效:延迟补偿和方法存根。 如果服务器方法调用可以在客户端正确模拟并因此在没有往返服务器的情况下立即执行,您可以定义称为方法存根(或模拟)的东西。

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

当然,服务器最终会在数据库中插入什么,这意味着当执行服务器端twin方法时,它的操作将优先并替换插入本地数据库中的内容。

要定义这种方法存根,您只需在客户端代码上定义相同的服务器方法名称。 如果方法声明中共享代码中定义的(都运到客户端和服务器),你可以测试方法调用实际上是一个模拟通过检查isSimulation属性:

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

更新26/11/2014: @ steph643评论了我之前回答的最后部分实际上是错误的,这里是一个更正。

请注意,服务器方法调用总是可以使用同步语法来调用,因为服务器环境提供了足够的阻塞机制(光纤)。

在客户端但是,如果从一个方法存根返回的东西,它可以同步只有当你的另一桩内,您可以检索结果以同步的方式执行,即

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

考虑到Mongo集合操作(​​insert/update/delete)被实现为Meteor方法,并且它们的客户端版本正在实现可以同步执行的有效存根(对minimongo复制的本地数据库子集的修改),此行为有点奇怪。

+0

谢谢,不得不让我的头,但这帮了很多。 http://www.eventedmind.com/posts/meteor-methods – jaggy

+2

“如果您从方法存根中返回某些内容,它可以在客户端同步执行,并且可以按照常规方式检索结果。”这不是真的。无论是否存在存根,客户端发出的方法调用返回'undefined'。参看该文档:“在客户端,如果你没有传递回调,并且你不在一个存根内(这意味着你不从另一个存根中调用该方法),那么调用将返回未定义的,并且你将无法获得该方法的返回值“。这适用于是否将存根连接到该方法。 – steph643

+0

感谢您指出这一点,我也关注流星核心的话题。我在我的答案中引用了文档,他们明确指出方法存根的客户端同步执行只能在另一个方法调用中进行,但没有多大意义,所以我认为是相反的。 – saimeunt