gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 12:29:56 25 4
gpt4 key购买 nike

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

方法调用.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 方法调用等到上一个调用完成后再开始执行下一个调用?

我找到了 this关于 SO 的问题似乎很有希望,但问题更侧重于阻止从客户端调用方法的可能性。同样,接受的答案并不完全令人满意,因为它着重于使后续调用跳过 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 就会被提供返回值,但是 main 方法函数(仍在其原始纤程中运行)被阻止返回,直到该值已提供。

结果是,除非您取消阻止此方法,否则您将获得预期的输出,因为下一个方法调用不会开始,直到前一个方法返回。

更新

一般来说,任何带有回调的东西都会在当前 Fiber 关闭后将回调添加到事件循环中,因此超时、HTTP 调用、异步 DB 查询 - 所有这些都属于此类。如果你想在回调中重新创建方法的环境,你需要使用 Meteor.bindEnvironment否则你不能使用任何 Meteor API 功能。 This是一个古老但非常关于这个主题的视频。

关于javascript - 当我调用 Meteor.setTimeout() 时,为什么我的后续 Meteor 方法调用不会等待第一个方法完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28069273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com