2015-09-23 29 views
5

Stworzyłem bardzo prosty serwer przy użyciu Meteora, aby wysłać wiadomość e-mail po przekroczeniu limitu czasu. Kiedy używam limitu czasu, wiadomość zostanie pomyślnie wysłana, ale zostanie zgłoszony błąd: [Error: Can't wait without a fiber].Meteor [Błąd: nie można czekać bez błonnika] po wywołaniu Email.send

Oto mój kod:

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

Rozumiem, że mogę używać Meteor.wrapAsync stworzyć błonnika. Ale wrapAsync oczekuje, że będzie wywołanie zwrotne, a Email.send nie będzie używać wywołania zwrotnego.

Co należy zrobić, aby pozbyć się błędu?

Odpowiedz

9

Dzieje się tak, ponieważ podczas gdy twoja funkcja Meteor.startup działa wewnątrz Fibre (jak prawie wszystkie inne wywołania zwrotne Meteora), użyty setTimeout nie działa! Ze względu na naturę setTimeout będzie działał w górnym zakresie, poza światlem, w którym zdefiniowałeś i/lub wywołałeś funkcję.

Aby rozwiązać, można użyć coś jak Meteor.bindEnvironment:

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

A potem zrobić dla każdego wywołania setTimeout, co jest boleśnie twardy fakt.
Dobrze, że to nie jest prawda. Wystarczy użyć Meteor.setTimeout zamiast natywnej jednym:

Meteor.setTimeout(sendMail, eta_ms); 

Od docs:

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 liczniki zaledwie bindEnvironment then delay the call jak chciałeś.