【问题标题】:Meteor [Error: Can't wait without a fiber] after a call to Email.send调用 Email.send 后的 Meteor [错误:无法等待没有光纤]
【发布时间】:2015-12-21 09:15:11
【问题描述】:

我使用 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 callback timeout fiber


    【解决方案1】:

    这是因为当您的 Meteor.startup 函数在 Fiber 中运行时(就像几乎所有其他 Meteor 回调一样),您使用的 setTimeout 却没有!由于setTimeout 的性质,它将在您定义和/或调用函数的光纤之外的顶级范围内运行。

    要解决,您可以使用Meteor.bindEnvironment

    setTimeout(Meteor.bindEnvironment(sendMail), eta_ms);
    

    然后在每次调用 setTimeout 时都这样做,这是一个令人痛苦的事实。
    好在这实际上不是真的。只需使用Meteor.setTimeout 而不是原生的:

    Meteor.setTimeout(sendMail, eta_ms);
    

    来自文档:

    这些函数的工作方式与它们的原生 JavaScript 等效项一样。如果你调用原生函数,你会得到一个错误,指出 Meteor 代码必须始终在 Fiber 中运行,并建议使用 Meteor.bindEnvironment

    Meteor timers just bindEnvironment then delay the call as you want.

    【讨论】:

      猜你喜欢
      • 2017-11-04
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      • 1970-01-01
      • 2015-12-21
      • 2013-07-30
      • 2016-11-27
      • 2021-10-06
      相关资源
      最近更新 更多