我使用Meteor创建了一个非常简单的服务器,用于在超时后发送电子邮件。当我使用超时时,消息成功发送,但抛出错误:[Error: Can't wait without a fiber]
.
下面是我的代码:
if (Meteor.isServer) {
Meteor.startup(function () {
// <DUMMY VALUES: PLEASE CHANGE>
process.env.MAIL_URL = 'smtp://me%40example.com:PASSWORD@smtp.example.com:25';
var to = 'you@example.com'
var from = 'me@example.com'
// </DUMMY>
//
var subject = 'Message'
var message = "Hello Meteor"
var eta_ms = 10000
var timeout = setTimeout(sendMail, eta_ms);
console.log(eta_ms)
function sendMail() {
console.log("Sending...")
try {
Email.send({
to: to,
from: from,
subject: subject,
text: message
})
} catch (error) {
console.log("Email.send error:", error)
}
}
})
}
我知道我可以使用Meteor.wrapAsync
来创建一个纤维。但是wrapAsync
期望有一个回调调用,而Email.send
不使用回调。
我该怎么做才能摆脱这个错误?
发生这种情况是因为当您的Meteor.startup
函数在光纤中运行时(像几乎所有其他流星回调函数一样),您使用的setTimeout
不会!由于setTimeout
的性质,它将在顶层作用域上运行,在定义和/或调用该函数的纤维之外。
Meteor.bindEnvironment
:
setTimeout(Meteor.bindEnvironment(sendMail), eta_ms);
然后对setTimeout
的每个调用都这样做,这是一个痛苦的事实。
好在这不是真的。只需使用Meteor.setTimeout
而不是本地的:
Meteor.setTimeout(sendMail, eta_ms);
From the docs:
这些函数的工作方式就像它们的原生JavaScript等效函数一样。如果您调用本机函数,您将得到一个错误,指出Meteor代码必须始终在光纤中运行,并建议使用
Meteor.bindEnvironment
流星定时器只是bindEnvironment
然后延迟调用,因为你想。