繁体   English   中英

当我调用Meteor.setTimeout()时,为什么我的后续Meteor方法调用不等待第一个方法完成?

[英]Why will my subsequent Meteor method calls not wait for the first one to finish when I call Meteor.setTimeout()?

我对流星,纤维和未来都很新,我试图了解Meteor方法的工作原理。 据我所知,来自客户端的每个方法调用都会等待前一个方法完成。 这种信念主要基于Meteor文档中this.unblock()函数的文档。 但是,当我尝试使用Meteor.setTimeout()调用设置一个简单示例时,这似乎不是一个正确的假设。

methodCall.js:

if (Meteor.isClient) {
  Template.hello.events({
    'click button': function () {
      Meteor.call('test', function(error, result){
      });
    }
  });
}

if (Meteor.isServer) {
  Meteor.methods({
    test: function(){
      console.log("outside");
      Meteor.setTimeout(function(){
          console.log("inside");
          return 'done';
      }, 2000);
    }
  });
}

当多次触发'click button'事件时,终端输出如下:

outside
outside
outside
outside
inside
inside
inside
inside

并且不像我期望的那样在outsideinside之间交替。 我认为Meteor.setTimeout()上有一些非常相关的信息我不知道了,但我在文档中找不到任何指示此行为的内容。 我缺少什么,有没有办法让客户端的Meteor方法调用等到上一次调用完成后再开始执行下一个调用?

我发现这个问题似乎很有希望,但问题更侧重于阻止从客户端调用该方法的可能性。 同样,接受的答案并不完全令人满意,因为它侧重于使后续调用跳过Meteor方法的某些代码块而不是等待第一次调用完成。 这就是我想的答案,但我真的很想理解为什么方法调用不会被阻止,因为我觉得Meteor文档表明了这一点。

答案是setTimeout回调是在运行该方法的光纤之外执行的。 这意味着该方法实际上在调用setTimeout回调之前完成执行(返回undefined ),并且您获得了您观察到的行为。

要提供更好的测试(以及在方法中使用异步函数的示例),请尝试以下操作:

if (Meteor.isServer) {
  var Future = Npm.require('fibers/future');

  Meteor.methods({
    test: function(){
      var fut = new Future();
      console.log("outside");
      Meteor.setTimeout(function(){
          console.log("inside");
          fut.return('done');
          return 'done';
      }, 2000);
      return fut.wait();
    }
  });
}

你的setTimeout回调的返回值实际上并没有去任何地方,它只是缩减了那个函数(即回调, 而不是方法)。 上面写的方式,Future对象fut ,一旦回调运行就会提供返回值,但主要方法函数(仍在其原始光纤中运行)将被阻止返回,直到提供该值为止。

结果是,除非您unblock此方法,否则您将获得预期的输出,因为下一个方法调用在前一个方法调用返回之前不会启动。

UPDATE

通常,具有回调的任何内容都会在当前光纤关闭后将回调添加到事件循环中,因此超时,HTTP调用,异步数据库查询 - 所有这些都属于此类别。 如果要在回调中重新创建方法的环境,则需要使用Meteor.bindEnvironment否则无法使用任何Meteor API功能。 是一个关于这个主题的古老但非常好的视频。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM