2015-09-23 16 views
5

Ich habe einen sehr einfachen Server mit Meteor erstellt, um eine E-Mail nach einem Timeout zu senden. Wenn ich ein Zeitlimit verwende, wird die Nachricht erfolgreich gesendet, aber ein Fehler wird ausgelöst: [Error: Can't wait without a fiber].Meteor [Fehler: Kann nicht ohne eine Faser] nach einem Anruf an Email.Send

Hier ist mein Code:

if (Meteor.isServer) { 
    Meteor.startup(function() { 
    // <DUMMY VALUES: PLEASE CHANGE> 
    process.env.MAIL_URL = 'smtp://me%40example.com:[email protected]:25'; 
    var to = '[email protected]' 
    var from = '[email protected]' 
    // </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) 
     } 
    } 
    }) 
} 

Ich verstehe, dass ich Meteor.wrapAsync verwenden könnte eine Faser zu erstellen. Aber wrapAsync erwartet, dass es einen Rückruf zum Anrufen gibt, und Email.send verwendet keinen Rückruf.

Was soll ich tun, um den Fehler loszuwerden?

Antwort

9

Dies geschieht, weil während Ihre Meteor.startup Funktion innerhalb einer Fiber (wie fast alle anderen Meteor Callbacks) läuft, die setTimeout Sie nicht verwenden! Aufgrund der Art von setTimeout wird es auf dem oberen Bereich ausgeführt, außerhalb der Faser, in der Sie die Funktion definiert und/oder aufgerufen haben.

zu lösen, Sie so etwas wie Meteor.bindEnvironment verwenden:

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

Und dann tut so für jeden einzelnen Anruf zu setTimeout, die eine schmerzlich harten Tatsache ist.
Gut, dass es nicht wirklich stimmt. Verwenden Sie einfach Meteor.setTimeout anstelle der nativen ein:

Meteor.setTimeout(sendMail, eta_ms); 

Aus der Dokumentation:

These functions work just like their native JavaScript equivalents. If you call the native function, you'll get an error stating that Meteor code must always run within a Fiber, and advising to use Meteor.bindEnvironment

Meteor-Timer nur bindEnvironment then delay the call wie man wollte.