2015-09-23 12 views
5

Ho creato un server molto semplice che utilizza Meteor, per inviare un'email dopo un timeout. Quando utilizzo un timeout, il messaggio viene inviato correttamente ma viene generato un errore: [Error: Can't wait without a fiber].Meteor [Errore: impossibile attendere senza fibra] dopo una chiamata a Email.send

Ecco il mio codice:

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) 
     } 
    } 
    }) 
} 

ho capito che avrei potuto usare Meteor.wrapAsync per creare una fibra. Ma wrapAsync si aspetta che ci sia un callback per chiamare, e Email.send non usa una richiamata.

Cosa devo fare per eliminare l'errore?

risposta

9

Questo accade perché mentre la tua funzione Meteor.startup gira all'interno di una fibra (come quasi tutte le altre callback di Meteor), lo setTimeout che usi non lo fa! A causa della natura di setTimeout, verrà eseguito sullo scope superiore, al di fuori della fibra in cui è stata definita e/o chiamata la funzione.

da risolvere, si potrebbe usare qualcosa come Meteor.bindEnvironment:

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

E poi lo fanno per ogni singola chiamata a setTimeout, che è un fatto dolorosamente difficile.
Per fortuna non è vero. Basta usare Meteor.setTimeout al posto del nativo uno:

Meteor.setTimeout(sendMail, eta_ms); 

Dalla documentazione:

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

timer Meteor solo bindEnvironment then delay the call come si voleva.