如何理解客户端的异步Meteor.call

时间:2016-06-16 20:52:27

标签: javascript asynchronous meteor

我正在研究一个Meteor项目,并希望在客户端的模板助手中获得Meteor.call的返回值。首先,我只是在回调函数中设置一个变量,并在$peter=array('cs204'=>array(10,10,10)); $peter=array_merge($peter, array('cs366'=>array(7,8,9))); 之外得到变量的值。我发现Meteor.call完全没有执行后的代码。然后我搜索了一下并使用Session,它有效。但我真的不明白原因。这是我的原始代码和修改后的代码。任何人都可以为我解释一下吗?谢谢!

原始错误代码:html

Meteor.call

JS

 <div id="text-result-main">
   <h2>{{title}}</h2>
 </div>

收集text.js

Template.texts.helpers({
  title: function(){
    var index = Router.current().params.index;
    Meteor.call('getTitle', index,function(error, result){ 
       titles = result;
    });
    console.log(titles);
    return titles;
 }});

工作代码:js

Text = new Mongo.Collection("text");
Meteor.methods({
  'getTitle': function(myindex){
     return Text.findOne({index: myindex}).title;
  }});

请注意,我根本没有将Collection Text发布到客户端,因为它太大了。每当我在运行错误的代码时刷新页面,我都看不到“标题”的内容或在控制台上看到它。但是当我设置会话时,它会起作用。我真的不明白它是如何工作的。谢谢

3 个答案:

答案 0 :(得分:1)

有两个问题 Asynchronicity Reactivity

这种影响

Meteor.call('getTitle', index,function(error, result){ 
   titles = result;
});
流星调用中的

是以异步方式执行的。因此,立即调用助手的返回,并返回一个空值。

在浏览器的控制台中试用。

但是,当您使用会话变量时,为什么您的模板使用{{title}}正确呈现? 这是因为Session是一个被动数据源,这意味着对它的每次更改都会触发重新计算涉及这段数据的所有模板。

以下是时间表:

  • 方法称为

  • 返回空值

  • 执行方法,设置变量值

  • 如果变量是反应式数据源,则会重新计算模板。 (在您的情况下,会话是一个反应性数据源。)

更进一步

在这种情况下,我会使用反应式var,它与会话变量非常接近,但范围仅限于模板。

关于反应数据源的详细阅读:http://richsilv.github.io/meteor/meteor-reactive-data-types/

答案 1 :(得分:1)

问题在于Meteor.call()与回调配对时是异步的。

因此,当title()开始执行时,它不会等待您的Meteor.call()调用返回结果(或可能是错误)。它继续执行。这称为异步执行。

简而言之,您正在尝试记录titles中不存在的密钥Session的值(因为异步Meteor调用的状态未知,此时为时间)。

尝试将控制台日志语句移动到与Meteor.call()配对的回调中,您可以在Session成功设置后查看结果。

解决问题的方法是让Meteor.call()像这样同步:

Template.texts.helpers({
 title: function(){
      var index = Router.current().params.index;
      var result = Meteor.call('getTitle', index); // <--- this is synchronous code now
      Session.set("titles",result);
      console.log(Session.get("titles"));
      return Session.get("titles"); 
}});

删除回调会使Meteor.call()同步运行。

  

如果未在服务器上传递回调,则调用方法   将阻止,直到方法完成。它最终会回归   返回方法的值,否则会抛出异常   方法引发了异常。

(来自http://docs.meteor.com/api/methods.html#Meteor-call

答案 2 :(得分:0)

为什么不使用这样的东西:

title: function(){
    var index = Router.current().params.index;
    var a = Text.findOne({index: myindex}).title;
    console.log(a);
    return a;

没有方法